diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000..dc12061 --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,50 @@ +env: + es6: true + node: true + mocha: true + jquery: true +extends: 'eslint:recommended' +parserOptions: + ecmaVersion: 6 + sourceType: + - script +rules: + indent: + - error + - 4 + linebreak-style: + - error + - unix + quotes: + - error + - single + semi: + - error + - always + no-unused-vars: + - error + - args: none + no-console: off + no-case-declarations: off + curly: error + eqeqeq: error + no-throw-literal: error + strict: error + no-var: error + dot-notation: error + no-tabs: error + no-trailing-spaces: error + no-use-before-define: error + no-useless-call: error + no-with: error + operator-linebreak: error + require-jsdoc: + - error + - require: + ClassDeclaration: true + MethodDefinition: true + FunctionDeclaration: true + valid-jsdoc: + - error + - requireReturn: false + yoda: error diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f5eee4d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text eol=lf + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.js text +*.css text +*.html text +*.json text +*.sh text + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary \ No newline at end of file diff --git a/.gitignore b/.gitignore index bcdbc6f..a5167bf 100644 --- a/.gitignore +++ b/.gitignore @@ -39,11 +39,10 @@ jspm_packages # OSX files .DS_Store +# env.json Chapter00 package-lock.json -*.key -*.ppt -*.pptx + composer-logs *.bna # Logs diff --git a/Chapter03/createArchive.sh b/Chapter03/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter03/createArchive.sh +++ b/Chapter03/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter03/create_composer_docs.sh b/Chapter03/create_composer_docs.sh new file mode 100755 index 0000000..35e56da --- /dev/null +++ b/Chapter03/create_composer_docs.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +. ../common_OSX.sh + +CHAPTER_DIR="" +DIR="" +REPO_DIR="" +ADMIN_DIR="node_modules/composer-admin" +CLIENT_DIR="node_modules/composer-client" +CLI_DIR="node_modules/composer-cli" +COMMON_DIR="node_modules/composer-common" +HLFV1_DIR="node_modules/composer-connector-hlfv1" +RUNTIME_DIR="node_modules/composer-runtime" +declare -a elements=("${ADMIN_DIR}" "$CLIENT_DIR" "${COMMON_DIR}" "${HLFV1_DIR}" "${RUNTIME_DIR}") +declare -a folders=('Admin' 'Client' 'Common' 'hlfv1' 'Runtime') + + +# get current folder +showStep "getting current directory path" +getCurrent +CHAPTER_DIR=$DIR +showStep "Chapter dir is: ${CHAPTER_DIR}" +for i in "${elements[@]}" +do +# switch to folder + showStep "Changing to ${i}" + cd "${i}" + pwd +# generate docs + showStep "Generating Documentation" + if [ ! -e "jsdoc.json" ]; then + cp jsdoc.conf jsdoc.json + fi + jsdoc --pedantic --recurse -c jsdoc.json + cd ../../ +done + +# get current folder -1 + showStep "getting repo root folder" + cd ../ + pwd + getCurrent + REPO_DIR=$DIR + showStep "repo dir is: ${REPO_DIR}" + +# remove old folders + showStep "Removing old documentation folders" + cd Composer_Docs + pwd + for i in "${folders[@]}" + do + # switch to folder + showStep "removing old docs in ${i}" + rm -rf "${i}" + mkdir "${i}" + done +# copy new content + showStep "copying new content from node_modules in ${CHAPTER_DIR} to Composer_Docs in ${pwd}" + pwd + count=${#elements[@]} + for i in `seq 1 $count` + do + showStep "cp -R ${CHAPTER_DIR}/${elements[$i-1]}/out/ ${folders[$i-1]}" + cp -R ${CHAPTER_DIR}/${elements[$i-1]}/out/ ${folders[$i-1]} + done +# display message on how to access documentation + showStep "Hyperledger Composer API documentation has been generated for your current version of Composer. + You can access this information by navigating to the ${GREEN}Composer_Docs${RESET} folder in your repo + and opening the ${GREEN}index.html${RESET} file located there in your favorite browser" \ No newline at end of file diff --git a/Chapter03/deployNetwork.sh b/Chapter03/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter03/deployNetwork.sh +++ b/Chapter03/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter03/favicon.ico b/Chapter03/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter03/favicon.ico and b/Chapter03/favicon.ico differ diff --git a/Chapter03/network/package.json b/Chapter03/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter03/network/package.json +++ b/Chapter03/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter03/network/test/sample.js b/Chapter03/network/test/sample.js index 0ea5df1..8b40e13 100644 --- a/Chapter03/network/test/sample.js +++ b/Chapter03/network/test/sample.js @@ -14,18 +14,12 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -36,7 +30,28 @@ const financeCoID = 'GlobalFinancier'; const dispute = 'ordered products received but defective'; const resolve = 'defective products will be refunded'; const backorder = 'order received, products on backorder. Will be shipped in 2 weeks.'; +let shipper; +let provider; +let financeCo; let orderAmount = 0; +let orderStatus = { + 'Created': {'code': 1, 'text': 'Order Created'}, + 'Bought': {'code': 2, 'text': 'Order Purchased'}, + 'Cancelled': {'code': 3, 'text': 'Order Cancelled'}, + 'Ordered': {'code': 4, 'text': 'Order Submitted to Provider'}, + 'ShipRequest': {'code': 5, 'text': 'Shipping Requested'}, + 'Delivered': {'code': 6, 'text': 'Order Delivered'}, + 'Delivering': {'code': 15, 'text': 'Order being Delivered'}, + 'Backordered': {'code': 7, 'text': 'Order Backordered'}, + 'Dispute': {'code': 8, 'text': 'Order Disputed'}, + 'Resolve': {'code': 9, 'text': 'Order Dispute Resolved'}, + 'PayRequest': {'code': 10, 'text': 'Payment Requested'}, + 'Authorize': {'code': 11, 'text': 'Payment Approved'}, + 'Paid': {'code': 14, 'text': 'Payment Processed'}, + 'Refund': {'code': 12, 'text': 'Order Refund Requested'}, + 'Refunded': {'code': 13, 'text': 'Order Refunded'} +}; + /** * create an empty order @@ -49,23 +64,25 @@ function createOrderTemplate (_inbound) _inbound.orderNumber = ''; _inbound.amount = 0; _inbound.items = []; - _inbound.status = 'Order Created'; + _inbound.status = JSON.stringify(orderStatus.Created); _inbound.created = new Date().toISOString(); + _inbound.cancelled = ''; _inbound.ordered = ''; _inbound.bought = ''; _inbound.dateBackordered = ''; _inbound.requestShipment = ''; _inbound.delivered = ''; + _inbound.delivering = ''; _inbound.disputeOpened = ''; _inbound.disputeResolved = ''; _inbound.orderRefunded = ''; _inbound.paymentRequested = ''; + _inbound.approved = ''; _inbound.paid = ''; _inbound.dispute = ''; _inbound.resolve = ''; _inbound.backorder = ''; _inbound.refund = ''; - _inbound.vendors = []; return(_inbound); } /** @@ -87,52 +104,19 @@ function addItems (_inbound) orderAmount= _inbound.amount; return (_inbound); } -/** - * find a vendor in an array - * @param {vendor_type} _string - type of vendor to find (e.g. 'supplier', 'shipper', etc.) - * @param {vendor_array} _vendorArray - vendor array from order - * @returns {$identifier} - returns the identifier if found else -1 - * @utility - */ -function getVendor(_string, _vendorArray) -{ - for (let each in _vendorArray) - {for (let _prop in JSON.parse(_vendorArray[each])) - {if (_prop === _string){return (JSON.parse(_vendorArray[each])[_string]);}}} - return(-1); -} - -describe('Finance Network', () => { - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { it('should be able to create an order', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the buyer const buyer = factory.newResource(NS, 'Buyer', buyerID); buyer.companyName = 'billybob computing'; @@ -141,6 +125,18 @@ describe('Finance Network', () => { const seller = factory.newResource(NS, 'Seller', sellerID); seller.companyName = 'Simon PC Hardware, Inc'; + // create the provider + provider = factory.newResource(NS, 'Provider', providerID); + provider.companyName = 'Ginsu Knife Specialists'; + + // create the shipper + shipper = factory.newResource(NS, 'Shipper', shipperID); + shipper.companyName = 'Fastest Ever Shippers'; + + // create the financeCo + financeCo = factory.newResource(NS, 'FinanceCo', financeCoID); + financeCo.companyName = 'The Global Financier'; + // create the order let order = factory.newResource(NS, 'Order', orderNo); order = createOrderTemplate(order); @@ -152,13 +148,17 @@ describe('Finance Network', () => { order.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier); order.seller = factory.newRelationship(NS, 'Seller', seller.$identifier); + order.provider = factory.newRelationship(NS, 'Provider', provider.$identifier); + order.shipper = factory.newRelationship(NS, 'Shipper', shipper.$identifier); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier); createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); createNew.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier); createNew.seller = factory.newRelationship(NS, 'Seller', seller.$identifier); createNew.amount = order.amount; // the buyer should of the commodity should be buyer //order.buyer.$identifier.should.equal(buyer.$identifier); - order.status.should.equal('Order Created'); + JSON.parse(order.status).text.should.equal(orderStatus.Created.text); order.amount.should.equal(orderAmount); createNew.amount.should.equal(orderAmount); createNew.order.$identifier.should.equal(orderNo); @@ -174,7 +174,7 @@ describe('Finance Network', () => { }) .then((participantRegistry) => { // add the buyer and seller - return participantRegistry.addAll([buyer, seller]); + return participantRegistry.addAll([buyer, seller, shipper, provider]); }) .then(() => { // submit the transaction @@ -226,7 +226,7 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.buyer.$identifier.should.equal(buyerID); - newOrder.status.should.equal('Purchased'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Bought.text); }); }); @@ -238,18 +238,10 @@ describe('Finance Network', () => { it('should be able to issue a supplier order', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the provider - const provider = factory.newResource(NS, 'Provider', providerID); - provider.companyName = 'Ginsu Knife Specialists'; - // create the buy transaction const orderNow = factory.newTransaction(NS, 'OrderFromSupplier'); return businessNetworkConnection.getParticipantRegistry(NS + '.Provider') - .then((participantRegistry) => { - // add the provider - return participantRegistry.addAll([provider]); - }) .then(() => { return businessNetworkConnection.getAssetRegistry(NS + '.Order'); }) @@ -263,6 +255,7 @@ describe('Finance Network', () => { orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); orderNow.provider = factory.newRelationship(NS, 'Provider', providerID); + orderNow.seller = factory.newRelationship(NS, 'Seller', sellerID); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) .then(() => { @@ -274,9 +267,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('supplier', newOrder.vendors); - vendor.should.equal(providerID); - newOrder.status.should.equal('Ordered From Supplier'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Ordered.text); }); }); @@ -287,10 +278,6 @@ describe('Finance Network', () => { it('should be able to issue a request to ship product', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the shipper - const shipper = factory.newResource(NS, 'Shipper', shipperID); - shipper.companyName = 'Fastest Ever Shippers'; - // create the buy transaction const orderNow = factory.newTransaction(NS, 'RequestShipping'); @@ -311,6 +298,7 @@ describe('Finance Network', () => { newOrder.$identifier.should.equal(orderNo); orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); + orderNow.provider = factory.newRelationship(NS, 'Provider', providerID); orderNow.shipper = factory.newRelationship(NS, 'Shipper', shipperID); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) @@ -323,9 +311,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('shipper', newOrder.vendors); - vendor.should.equal(shipperID); - newOrder.status.should.equal('Shipment Requested'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.ShipRequest.text); }); }); @@ -361,9 +347,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('shipper', newOrder.vendors); - vendor.should.equal(shipperID); - newOrder.status.should.equal('Delivered'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Delivered.text); }); }); @@ -375,10 +359,6 @@ describe('Finance Network', () => { it('should be able to issue a request to request payment for a product', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the financeCo - const financeCo = factory.newResource(NS, 'FinanceCo', financeCoID); - financeCo.companyName = 'The Global Financier'; - // create the buy transaction const orderNow = factory.newTransaction(NS, 'RequestPayment'); @@ -400,7 +380,6 @@ describe('Finance Network', () => { orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) @@ -413,17 +392,53 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('financeCo', newOrder.vendors); - vendor.should.equal(financeCoID); - newOrder.status.should.equal('Payment Requested'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.PayRequest.text); }); }); }); }); - describe('#issuePayment', () => { + describe('#authorizePayment', () => { - it('should be able to record a product payment', () => { + it('should be able to record a approval for order payment', () => { + const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + + // create the Deliver transaction + const orderNow = factory.newTransaction(NS, 'AuthorizePayment'); + + return businessNetworkConnection.getAssetRegistry(NS + '.Order') + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + newOrder.buyer.$identifier.should.equal(buyerID); + newOrder.$identifier.should.equal(orderNo); + + orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); + orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); + // submit the transaction + return businessNetworkConnection.submitTransaction(orderNow) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS + '.Order'); + }) + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + // the owner of the commodity should be buyer + JSON.parse(newOrder.status).text.should.equal(orderStatus.Authorize.text); + }); + + }); + }); + }); + + describe('#Pay', () => { + + it('should be able to record an order payment', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); // create the Deliver transaction @@ -452,9 +467,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('financeCo', newOrder.vendors); - vendor.should.equal(financeCoID); - newOrder.status.should.equal('Paid'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Paid.text); }); }); @@ -495,7 +508,7 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.dispute.should.equal(dispute); - newOrder.status.should.equal('In Dispute'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Dispute.text); }); }); @@ -523,6 +536,8 @@ describe('Finance Network', () => { orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier); + orderNow.shipper = factory.newRelationship(NS, 'Shipper', newOrder.shipper.$identifier); + orderNow.provider = factory.newRelationship(NS, 'Provider', provider.$identifier); orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) @@ -536,7 +551,7 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.resolve.should.equal(resolve); - newOrder.status.should.equal('Resolved'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Resolve.text); }); }); @@ -562,7 +577,7 @@ describe('Finance Network', () => { orderNow.backorder = backorder; orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); - orderNow.provider = factory.newRelationship(NS, 'Provider', JSON.parse(newOrder.vendors[0]).supplier); + orderNow.provider = factory.newRelationship(NS, 'Provider', providerID); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) .then(() => { @@ -575,7 +590,44 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.backorder.should.equal(backorder); - newOrder.status.should.equal('Backordered'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Backordered.text); + }); + + }); + }); + }); + describe('#issueCancel', () => { + + it('should be able to record an order cancellation', () => { + const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + + // create the Deliver transaction + const orderNow = factory.newTransaction(NS, 'OrderCancel'); + + return businessNetworkConnection.getAssetRegistry(NS + '.Order') + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + newOrder.buyer.$identifier.should.equal(buyerID); + newOrder.$identifier.should.equal(orderNo); + + orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); + orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier); + orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); + // submit the transaction + return businessNetworkConnection.submitTransaction(orderNow) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS + '.Order'); + }) + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + // the owner of the commodity should be buyer + JSON.parse(newOrder.status).text.should.equal(orderStatus.Cancelled.text); }); }); diff --git a/Chapter03/package.json b/Chapter03/package.json index 01578b9..57535e3 100644 --- a/Chapter03/package.json +++ b/Chapter03/package.json @@ -1,6 +1,6 @@ { "engines": { - "composer": "^0.10.0" + "composer": "" }, "name": "zerotoblockchain-network", "version": "0.1.6", @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -33,15 +34,17 @@ "author": "Bob Dill, IBM Distinguished Engineer", "license": "Apache-2.0", "devDependencies": { + "extend": "", "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -83,5 +86,26 @@ "branches": 100, "functions": 100, "lines": 100 + }, + "dependencies": { + "body-parser": "^1.18.1", + "cfenv": "^1.0.4", + "connect-busboy": "0.0.2", + "cookie-parser": "^1.4.3", + "date-format": "", + "ejs": "", + "express": "^4.15.4", + "express-session": "^1.15.5", + "fabric-client": "^1.0.2", + "fs": "0.0.1-security", + "http": "0.0.0", + "https": "^1.0.0", + "mime": "^2.0.2", + "os": "^0.1.1", + "path": "^0.12.7", + "sleep": "^5.1.1", + "uuid": "^3.1.0", + "vcap_services": "^0.3.4", + "websocket": "^1.0.24" } } diff --git a/Chapter03/shutdown.sh b/Chapter03/shutdown.sh index 3fb615d..f270d76 100755 --- a/Chapter03/shutdown.sh +++ b/Chapter03/shutdown.sh @@ -1,40 +1,11 @@ #!/bin/bash - YELLOW='\033[1;33m' - RED='\033[1;31m' - GREEN='\033[1;32m' - RESET='\033[0m' +. ../common_OSX.sh -# indent text on echo -function indent() { - c='s/^/ /' - case $(uname) in - Darwin) sed -l "$c";; - *) sed -u "$c";; - esac -} - -# Grab the current directory -function getCurrent() - { - showStep "getting current directory" - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - THIS_SCRIPT=`basename "$0"` - showStep "Running '${THIS_SCRIPT}'" - } - -# displays where we are, uses the indent function (above) to indent each line -function showStep () - { - echo -e "${YELLOW}=====================================================" | indent - echo -e "${RESET}-----> $*" | indent - echo -e "${YELLOW}=====================================================${RESET}" | indent - } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "stopping fabric" ./stopFabric.sh showStep "tear down" ./teardownFabric.sh -showStep "shut down complete"#!/bin/bash - \ No newline at end of file +showStep "shut down complete" \ No newline at end of file diff --git a/Chapter03/startup.sh b/Chapter03/startup.sh index b4c76e2..a4602d8 100755 --- a/Chapter03/startup.sh +++ b/Chapter03/startup.sh @@ -35,6 +35,12 @@ showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" ~/fabric-tools/startFabric.sh -showStep "creating new composer profile (required with each restart)" -~/fabric-tools/createComposerProfile.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter03/z2c_login b/Chapter03/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter03/z2c_login +++ b/Chapter03/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf index a02f0e5..403f61b 100644 Binary files a/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf and b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pdf differ diff --git a/Chapter04/Documentation/Chinese/Z2B_Chapter04.pptx b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pptx new file mode 100644 index 0000000..b57eb6c Binary files /dev/null and b/Chapter04/Documentation/Chinese/Z2B_Chapter04.pptx differ diff --git a/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf index 7222a59..1368a58 100644 Binary files a/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf and b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pdf differ diff --git a/Chapter04/Documentation/Espanol/Z2B_Chapter04.pptx b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pptx new file mode 100644 index 0000000..3068903 Binary files /dev/null and b/Chapter04/Documentation/Espanol/Z2B_Chapter04.pptx differ diff --git a/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf index 130b9c1..2906dd7 100644 Binary files a/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf and b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pdf differ diff --git a/Chapter04/Documentation/Japanese/Z2B_Chapter04.pptx b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pptx new file mode 100644 index 0000000..da31099 Binary files /dev/null and b/Chapter04/Documentation/Japanese/Z2B_Chapter04.pptx differ diff --git a/Chapter04/Documentation/Z2B Chapter04.pdf b/Chapter04/Documentation/Z2B Chapter04.pdf index 2f4ed6f..8fdca08 100644 Binary files a/Chapter04/Documentation/Z2B Chapter04.pdf and b/Chapter04/Documentation/Z2B Chapter04.pdf differ diff --git a/Chapter04/Documentation/answers/lib/sample_complete.js b/Chapter04/Documentation/answers/lib/sample_complete.js index 1036514..0c5bd5c 100644 --- a/Chapter04/Documentation/answers/lib/sample_complete.js +++ b/Chapter04/Documentation/answers/lib/sample_complete.js @@ -253,16 +253,3 @@ function BackOrder(purchase) { return assetRegistry.update(purchase.order); }); } - -/** - * display using console.log the properties of each property in the inbound object - * @param {displayObjectProperties} _string - string name of object - * @param {displayObjectProperties} _object - the object to be parsed - * @utility - */ -function displayObjectValues (_string, _object) -{ - for (var prop in _object){ - console.log(_string+'-->'+prop+':\t '+(((typeof(_object[prop]) === 'object') || (typeof(_object[prop]) === 'function')) ? typeof(_object[prop]) : _object[prop])); - } -} \ No newline at end of file diff --git a/Chapter04/Documentation/answers/placeholder_complete.js b/Chapter04/Documentation/answers/placeholder_complete.js deleted file mode 100644 index c5996b4..0000000 --- a/Chapter04/Documentation/answers/placeholder_complete.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var extend = require('extend'); -var watson = require('watson-developer-cloud'); -var vcapServices = require('vcap_services'); - -var config = require('../../env.json'); - -exports.placeholder = function(req, res) { - -} diff --git a/Chapter04/Documentation/answers/test/sample_complete.js b/Chapter04/Documentation/answers/test/sample_complete.js index 1c3e3e6..e5e48e8 100644 --- a/Chapter04/Documentation/answers/test/sample_complete.js +++ b/Chapter04/Documentation/answers/test/sample_complete.js @@ -15,17 +15,17 @@ 'use strict'; const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; + +const hlc_idCard = require('composer-common').IdCard; const path = require('path'); +const _home = require('os').homedir(); require('chai').should(); const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -58,6 +58,7 @@ let orderStatus = { 'Refunded': {'code': 13, 'text': 'Order Refunded'} }; + /** * create an empty order * @param {createOrderTemplate} _inbound - Order created with factory.newResource(NS, 'Order', orderNo) @@ -110,30 +111,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter04/createArchive.sh b/Chapter04/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter04/createArchive.sh +++ b/Chapter04/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter04/create_composer_docs.sh b/Chapter04/create_composer_docs.sh index 27aae4c..35e56da 100755 --- a/Chapter04/create_composer_docs.sh +++ b/Chapter04/create_composer_docs.sh @@ -1,37 +1,7 @@ #!/bin/bash - YELLOW='\033[1;33m' - RED='\033[1;31m' - GREEN='\033[1;32m' - RESET='\033[0m' +. ../common_OSX.sh -# indent text on echo -function indent() { - c='s/^/ /' - case $(uname) in - Darwin) sed -l "$c";; - *) sed -u "$c";; - esac -} - -# Grab the current directory -function getCurrent() - { - showStep "getting current directory" - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - THIS_SCRIPT=`basename "$0"` - showStep "Running '${THIS_SCRIPT}'" - echo $DIR - - } - -# displays where we are, uses the indent function (above) to indent each line -function showStep () - { - echo -e "${YELLOW}=====================================================" | indent - echo -e "${RESET}-----> $*" | indent - echo -e "${YELLOW}=====================================================${RESET}" | indent - } CHAPTER_DIR="" DIR="" REPO_DIR="" @@ -49,7 +19,7 @@ declare -a folders=('Admin' 'Client' 'Common' 'hlfv1' 'Runtime') showStep "getting current directory path" getCurrent CHAPTER_DIR=$DIR -echo "${CHAPTER_DIR}" +showStep "Chapter dir is: ${CHAPTER_DIR}" for i in "${elements[@]}" do # switch to folder @@ -71,6 +41,7 @@ done pwd getCurrent REPO_DIR=$DIR + showStep "repo dir is: ${REPO_DIR}" # remove old folders showStep "Removing old documentation folders" @@ -84,7 +55,7 @@ done mkdir "${i}" done # copy new content - showStep "copying new content" + showStep "copying new content from node_modules in ${CHAPTER_DIR} to Composer_Docs in ${pwd}" pwd count=${#elements[@]} for i in `seq 1 $count` diff --git a/Chapter04/deployNetwork.sh b/Chapter04/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter04/deployNetwork.sh +++ b/Chapter04/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter04/favicon.ico b/Chapter04/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter04/favicon.ico and b/Chapter04/favicon.ico differ diff --git a/Chapter04/network/dist/networkadmin.card b/Chapter04/network/dist/networkadmin.card new file mode 100644 index 0000000..7911698 Binary files /dev/null and b/Chapter04/network/dist/networkadmin.card differ diff --git a/Chapter04/network/dist/placeholder.txt b/Chapter04/network/dist/placeholder.txt index 6773299..b3a4252 100644 --- a/Chapter04/network/dist/placeholder.txt +++ b/Chapter04/network/dist/placeholder.txt @@ -1 +1 @@ -placeholder to force dist to clone +placeholder \ No newline at end of file diff --git a/Chapter04/network/features/sample.feature b/Chapter04/network/features/sample.feature deleted file mode 100644 index 4c5ba21..0000000 --- a/Chapter04/network/features/sample.feature +++ /dev/null @@ -1,176 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -Feature: Sample - - Background: - Given I have deployed the business network definition .. - And I have added the following participants of type org.acme.sample.SampleParticipant - | participantId | firstName | lastName | - | alice@email.com | Alice | A | - | bob@email.com | Bob | B | - And I have added the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 1 | alice@email.com | 10 | - | 2 | bob@email.com | 20 | - And I have issued the participant org.acme.sample.SampleParticipant#alice@email.com with the identity alice1 - And I have issued the participant org.acme.sample.SampleParticipant#bob@email.com with the identity bob1 - - Scenario: Alice can read all of the assets - When I use the identity alice1 - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 1 | alice@email.com | 10 | - | 2 | bob@email.com | 20 | - - Scenario: Bob can read all of the assets - When I use the identity alice1 - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 1 | alice@email.com | 10 | - | 2 | bob@email.com | 20 | - - Scenario: Alice can add assets that she owns - When I use the identity alice1 - And I add the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 3 | alice@email.com | 30 | - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 3 | alice@email.com | 30 | - - Scenario: Alice cannot add assets that Bob owns - When I use the identity alice1 - And I add the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 3 | bob@email.com | 30 | - Then I should get an error matching /does not have .* access to resource/ - - Scenario: Bob can add assets that he owns - When I use the identity bob1 - And I add the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 4 | bob@email.com | 40 | - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 4 | bob@email.com | 40 | - - Scenario: Bob cannot add assets that Alice owns - When I use the identity bob1 - And I add the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 4 | alice@email.com | 40 | - Then I should get an error matching /does not have .* access to resource/ - - Scenario: Alice can update her assets - When I use the identity alice1 - And I update the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 1 | alice@email.com | 50 | - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 1 | alice@email.com | 50 | - - Scenario: Alice cannot update Bob's assets - When I use the identity alice1 - And I update the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 2 | bob@email.com | 50 | - Then I should get an error matching /does not have .* access to resource/ - - Scenario: Bob can update his assets - When I use the identity bob1 - And I update the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 2 | bob@email.com | 60 | - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 2 | bob@email.com | 60 | - - Scenario: Bob cannot update Alice's assets - When I use the identity bob1 - And I update the following asset of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 1 | alice@email.com | 60 | - Then I should get an error matching /does not have .* access to resource/ - - Scenario: Alice can remove her assets - When I use the identity alice1 - And I remove the following asset of type org.acme.sample.SampleAsset - | assetId | - | 1 | - Then I should not have the following assets of type org.acme.sample.SampleAsset - | assetId | - | 1 | - - Scenario: Alice cannot remove Bob's assets - When I use the identity alice1 - And I remove the following asset of type org.acme.sample.SampleAsset - | assetId | - | 2 | - Then I should get an error matching /does not have .* access to resource/ - - Scenario: Bob can remove his assets - When I use the identity bob1 - And I remove the following asset of type org.acme.sample.SampleAsset - | assetId | - | 2 | - Then I should not have the following assets of type org.acme.sample.SampleAsset - | assetId | - | 2 | - - Scenario: Bob cannot remove Alice's assets - When I use the identity bob1 - And I remove the following asset of type org.acme.sample.SampleAsset - | assetId | - | 1 | - Then I should get an error matching /does not have .* access to resource/ - - Scenario: Alice can submit a transaction for her assets - When I use the identity alice1 - And I submit the following transaction of type org.acme.sample.SampleTransaction - | asset | newValue | - | 1 | 50 | - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 1 | alice@email.com | 50 | - And I should have received the following event of type org.acme.sample.SampleEvent - | asset | oldValue | newValue | - | 1 | 10 | 50 | - - Scenario: Alice cannot submit a transaction for Bob's assets - When I use the identity alice1 - And I submit the following transaction of type org.acme.sample.SampleTransaction - | asset | newValue | - | 2 | 50 | - Then I should get an error matching /does not have .* access to resource/ - - Scenario: Bob can submit a transaction for his assets - When I use the identity bob1 - And I submit the following transaction of type org.acme.sample.SampleTransaction - | asset | newValue | - | 2 | 60 | - Then I should have the following assets of type org.acme.sample.SampleAsset - | assetId | owner | value | - | 2 | bob@email.com | 60 | - And I should have received the following event of type org.acme.sample.SampleEvent - | asset | oldValue | newValue | - | 2 | 20 | 60 | - - Scenario: Bob cannot submit a transaction for Alice's assets - When I use the identity bob1 - And I submit the following transaction of type org.acme.sample.SampleTransaction - | asset | newValue | - | 1 | 60 | - Then I should get an error matching /does not have .* access to resource/ diff --git a/Chapter04/network/features/support/index.js b/Chapter04/network/features/support/index.js deleted file mode 100644 index 7325f1f..0000000 --- a/Chapter04/network/features/support/index.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const composerSteps = require('composer-cucumber-steps'); -const cucumber = require('cucumber'); - -module.exports = function () { - composerSteps.call(this); -}; - -if (cucumber.defineSupportCode) { - cucumber.defineSupportCode((context) => { - module.exports.call(context); - }); -} diff --git a/Chapter04/network/lib/sample.js b/Chapter04/network/lib/sample.js index 6a82d26..1036514 100644 --- a/Chapter04/network/lib/sample.js +++ b/Chapter04/network/lib/sample.js @@ -12,6 +12,24 @@ * limitations under the License. */ +var orderStatus = { + Created: {code: 1, text: 'Order Created'}, + Bought: {code: 2, text: 'Order Purchased'}, + Cancelled: {code: 3, text: 'Order Cancelled'}, + Ordered: {code: 4, text: 'Order Submitted to Provider'}, + ShipRequest: {code: 5, text: 'Shipping Requested'}, + Delivered: {code: 6, text: 'Order Delivered'}, + Delivering: {code: 15, text: 'Order being Delivered'}, + Backordered: {code: 7, text: 'Order Backordered'}, + Dispute: {code: 8, text: 'Order Disputed'}, + Resolve: {code: 9, text: 'Order Dispute Resolved'}, + PayRequest: {code: 10, text: 'Payment Requested'}, + Authorize: {code: 11, text: 'Payment Approved'}, + Paid: {code: 14, text: 'Payment Processed'}, + Refund: {code: 12, text: 'Order Refund Requested'}, + Refunded: {code: 13, text: 'Order Refunded'} +}; + /** * create an order to purchase * @param {org.acme.Z2BTestNetwork.CreateOrder} purchase - the order to be processed @@ -20,8 +38,9 @@ function CreateOrder(purchase) { purchase.order.buyer = purchase.buyer; purchase.order.amount = purchase.amount; + purchase.order.financeCo = purchase.financeCo; purchase.order.created = new Date().toISOString(); - purchase.order.status = "Order Created"; + purchase.order.status = JSON.stringify(orderStatus.Created); return getAssetRegistry('org.acme.Z2BTestNetwork.Order') .then(function (assetRegistry) { return assetRegistry.update(purchase.order); @@ -33,7 +52,35 @@ function CreateOrder(purchase) { * @transaction */ function Buy(purchase) { - + if (purchase.order.status = JSON.stringify(orderStatus.Created)) + { + purchase.order.buyer = purchase.buyer; + purchase.order.seller = purchase.seller; + purchase.order.bought = new Date().toISOString(); + purchase.order.status = JSON.stringify(orderStatus.Bought); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); + } +} +/** + * Record a request to cancel an order + * @param {org.acme.Z2BTestNetwork.OrderCancel} purchase - the order to be processed + * @transaction + */ +function OrderCancel(purchase) { + if ((purchase.order.status = JSON.stringify(orderStatus.Created)) || (purchase.order.status = JSON.stringify(orderStatus.Bought))) + { + purchase.order.buyer = purchase.buyer; + purchase.order.seller = purchase.seller; + purchase.order.cancelled = new Date().toISOString(); + purchase.order.status = JSON.stringify(orderStatus.Cancelled); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); + } } /** * Record a request to order by seller from supplier @@ -41,7 +88,16 @@ function Buy(purchase) { * @transaction */ function OrderFromSupplier(purchase) { - + if (purchase.order.status = JSON.stringify(orderStatus.Bought)) + { + purchase.order.provider = purchase.provider; + purchase.order.ordered = new Date().toISOString(); + purchase.order.status = JSON.stringify(orderStatus.Ordered); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); + } } /** * Record a request to ship by supplier to shipper @@ -49,7 +105,34 @@ function OrderFromSupplier(purchase) { * @transaction */ function RequestShipping(purchase) { - + if (purchase.order.status = JSON.stringify(orderStatus.Ordered)) + { + purchase.order.shipper = purchase.shipper; + purchase.order.requestShipment = new Date().toISOString(); + purchase.order.status = JSON.stringify(orderStatus.ShipRequest); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); + } +} +/** + * Record a delivery by shipper + * @param {org.acme.Z2BTestNetwork.Delivering} purchase - the order to be processed + * @transaction + */ +function Delivering(purchase) { + if ((purchase.order.status = JSON.stringify(orderStatus.ShipRequest)) || (JSON.parse(purchase.order.status).code = orderStatus.Delivering.code)) + { + purchase.order.delivering = new Date().toISOString(); + var _status = orderStatus.Delivering; + _status.text += ' '+purchase.deliveryStatus; + purchase.order.status = JSON.stringify(_status); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); + } } /** * Record a delivery by shipper @@ -57,7 +140,15 @@ function RequestShipping(purchase) { * @transaction */ function Deliver(purchase) { - + if ((purchase.order.status = JSON.stringify(orderStatus.ShipRequest)) || (JSON.parse(purchase.order.status).code = orderStatus.Delivering.code)) + { + purchase.order.delivered = new Date().toISOString(); + purchase.order.status = JSON.stringify(orderStatus.Delivered); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); + } } /** * Record a request for payment by the seller @@ -65,7 +156,30 @@ function Deliver(purchase) { * @transaction */ function RequestPayment(purchase) { - + if ((JSON.parse(purchase.order.status).text == orderStatus.Delivered.text) || (JSON.parse(purchase.order.status).text == orderStatus.Resolve.text)) + {purchase.order.status = JSON.stringify(orderStatus.PayRequest); + purchase.order.financeCo = purchase.financeCo; + purchase.order.paymentRequested = new Date().toISOString(); + } + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); +} + /** + * Record a payment to the seller + * @param {org.acme.Z2BTestNetwork.AuthorizePayment} purchase - the order to be processed + * @transaction + */ +function AuthorizePayment(purchase) { + if ((JSON.parse(purchase.order.status).text == orderStatus.PayRequest.text ) || (JSON.parse(purchase.order.status).text == orderStatus.Resolve.text )) + {purchase.order.status = JSON.stringify(orderStatus.Authorize); + purchase.order.approved = new Date().toISOString(); + } + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); } /** * Record a payment to the seller @@ -73,7 +187,14 @@ function RequestPayment(purchase) { * @transaction */ function Pay(purchase) { - + if (JSON.parse(purchase.order.status).text == orderStatus.Authorize.text ) + {purchase.order.status = JSON.stringify(orderStatus.Paid); + purchase.order.paid = new Date().toISOString(); + } + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); } /** * Record a dispute by the buyer @@ -81,7 +202,13 @@ function Pay(purchase) { * @transaction */ function Dispute(purchase) { - + purchase.order.status = JSON.stringify(orderStatus.Dispute); + purchase.order.dispute = purchase.dispute; + purchase.order.disputeOpened = new Date().toISOString(); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); } /** * Resolve a seller initiated dispute @@ -89,7 +216,13 @@ function Dispute(purchase) { * @transaction */ function Resolve(purchase) { - + purchase.order.status = JSON.stringify(orderStatus.Resolve); + purchase.order.resolve = purchase.resolve; + purchase.order.disputeResolved = new Date().toISOString(); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); } /** * Record a refund to the buyer @@ -97,7 +230,13 @@ function Resolve(purchase) { * @transaction */ function Refund(purchase) { - + purchase.order.status = JSON.stringify(orderStatus.Refund); + purchase.order.refund = purchase.refund; + purchase.order.orderRefunded = new Date().toISOString(); + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); } /** * Record a backorder by the supplier @@ -105,18 +244,25 @@ function Refund(purchase) { * @transaction */ function BackOrder(purchase) { - + purchase.order.status = JSON.stringify(orderStatus.Backordered); + purchase.order.backorder = purchase.backorder; + purchase.order.dateBackordered = new Date().toISOString(); + purchase.order.provider = purchase.provider; + return getAssetRegistry('org.acme.Z2BTestNetwork.Order') + .then(function (assetRegistry) { + return assetRegistry.update(purchase.order); + }); } - /** + +/** * display using console.log the properties of each property in the inbound object * @param {displayObjectProperties} _string - string name of object * @param {displayObjectProperties} _object - the object to be parsed * @utility */ - function displayObjectValues (_string, _object) { for (var prop in _object){ console.log(_string+'-->'+prop+':\t '+(((typeof(_object[prop]) === 'object') || (typeof(_object[prop]) === 'function')) ? typeof(_object[prop]) : _object[prop])); } -} +} \ No newline at end of file diff --git a/Chapter04/network/models/events.cto b/Chapter04/network/models/events.cto index c55a608..ab9f549 100644 --- a/Chapter04/network/models/events.cto +++ b/Chapter04/network/models/events.cto @@ -23,4 +23,69 @@ abstract event BasicEvent { // notify seller, financeCo that an order has been placed event requested extends BasicEvent { o String orderNumber + o String sellerID + o String orderID +} + +// notify seller, supplier that a fulfillment request has been placed +event ordered extends BasicEvent { + o String orderNumber + o String providerID + o String orderID +} + +// notify seller, buyer that items are on backorder +event backordered extends BasicEvent { + o String orderNumber + o String sellerID + o String orderID +} + +// notify seller, buyer, shipper that shipper has been contacted +event shipRequest extends BasicEvent { + o String orderNumber + o String shipperID + o String orderID +} + +// notify seller, supplier, buyer that order has been delivered +event delivering extends BasicEvent { + o String orderNumber + o String buyerID + o String orderID +} + +// notify seller, supplier, buyer that order has been delivered +event delivered extends BasicEvent { + o String orderNumber + o String buyerID + o String orderID +} + +// notify seller, financeCo that order is in dispute +event dispute extends BasicEvent { + o String orderNumber + o String sellerID + o String orderID +} + +// notify seller, buyer that dispute has been resolved +event resolved extends BasicEvent { + o String orderNumber + o String sellerID + o String orderID +} + +// notify financeCo, buyer that a request for payment has been issued +event requestPayment extends BasicEvent { + o String buyerID + o String orderID + o String orderNumber +} + +// notify seller, buyer that order has been paid / +event Paid extends BasicEvent { + o String sellerID + o String orderID + o String orderNumber } diff --git a/Chapter04/network/models/sample.cto b/Chapter04/network/models/sample.cto index 1c5e8de..a803085 100644 --- a/Chapter04/network/models/sample.cto +++ b/Chapter04/network/models/sample.cto @@ -1,20 +1,131 @@ -/** - * Zero To Blockchain multi-party finance network - */ -namespace org.acme.Z2BTestNetwork -import composer.base.* -import composer.events.* - -participant Buyer identified by buyerID extends Member{ - o String buyerID -} - -asset Order identified by orderNumber { - o String orderNumber - -} - transaction CreateOrder { - o Integer amount - --> Order order - --> Buyer buyer -} +/** + * Zero To Blockchain multi-party finance network + */ +namespace org.acme.Z2BTestNetwork +import composer.base.* +import composer.events.* + +participant Buyer identified by buyerID extends Member{ + o String buyerID +} +participant Seller identified by sellerID extends Member{ + o String sellerID +} +participant Shipper identified by shipperID extends Member { + o String shipperID +} +participant Provider identified by providerID extends Member { + o String providerID +} +participant FinanceCo identified by financeCoID extends Member { + o String financeCoID +} + +asset Order identified by orderNumber { + o String orderNumber + o String[] items + o String status + o String dispute + o String resolve + o String backorder + o String refund + o Integer amount + o String created + o String bought + o String cancelled + o String ordered + o String dateBackordered + o String requestShipment + o String delivered + o String delivering + o String disputeOpened + o String disputeResolved + o String paymentRequested + o String orderRefunded + o String approved + o String paid + --> Provider provider + --> Shipper shipper + --> Buyer buyer + --> Seller seller + --> FinanceCo financeCo + +} + transaction CreateOrder { + o Integer amount + --> Order order + --> Buyer buyer + --> Seller seller + --> FinanceCo financeCo +} + transaction OrderCancel { + --> Order order + --> Buyer buyer + --> Seller seller +} + transaction Buy { + --> Order order + --> Buyer buyer + --> Seller seller +} + transaction OrderFromSupplier { + --> Order order + --> Provider provider + --> Seller seller +} + transaction RequestShipping { + --> Order order + --> Shipper shipper + --> Provider provider +} + transaction Deliver { + --> Order order + --> Shipper shipper +} + transaction Delivering { + o String deliveryStatus + --> Order order + --> Shipper shipper +} + transaction BackOrder { + o String backorder + --> Order order + --> Provider provider +} + transaction Dispute { + o String dispute + --> Order order + --> Buyer buyer + --> Seller seller + --> FinanceCo financeCo +} + transaction Resolve { + o String resolve + --> Order order + --> Buyer buyer + --> Seller seller + --> Shipper shipper + --> Provider provider + --> FinanceCo financeCo +} + transaction RequestPayment { + --> Order order + --> Seller seller + --> FinanceCo financeCo +} + transaction AuthorizePayment { + --> Order order + --> Buyer buyer + --> FinanceCo financeCo +} + transaction Pay { + --> Order order + --> Seller seller + --> FinanceCo financeCo +} + transaction Refund { + o String refund + --> Order order + --> Seller seller + --> FinanceCo financeCo +} diff --git a/Chapter04/network/package.json b/Chapter04/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter04/network/package.json +++ b/Chapter04/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter04/network/test/sample.js b/Chapter04/network/test/sample.js index 0ea5df1..f6e7ea5 100644 --- a/Chapter04/network/test/sample.js +++ b/Chapter04/network/test/sample.js @@ -14,18 +14,12 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +// const network = 'zerotoblockchain-network'; +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -36,7 +30,28 @@ const financeCoID = 'GlobalFinancier'; const dispute = 'ordered products received but defective'; const resolve = 'defective products will be refunded'; const backorder = 'order received, products on backorder. Will be shipped in 2 weeks.'; +let shipper; +let provider; +let financeCo; let orderAmount = 0; +let orderStatus = { + 'Created': {'code': 1, 'text': 'Order Created'}, + 'Bought': {'code': 2, 'text': 'Order Purchased'}, + 'Cancelled': {'code': 3, 'text': 'Order Cancelled'}, + 'Ordered': {'code': 4, 'text': 'Order Submitted to Provider'}, + 'ShipRequest': {'code': 5, 'text': 'Shipping Requested'}, + 'Delivered': {'code': 6, 'text': 'Order Delivered'}, + 'Delivering': {'code': 15, 'text': 'Order being Delivered'}, + 'Backordered': {'code': 7, 'text': 'Order Backordered'}, + 'Dispute': {'code': 8, 'text': 'Order Disputed'}, + 'Resolve': {'code': 9, 'text': 'Order Dispute Resolved'}, + 'PayRequest': {'code': 10, 'text': 'Payment Requested'}, + 'Authorize': {'code': 11, 'text': 'Payment Approved'}, + 'Paid': {'code': 14, 'text': 'Payment Processed'}, + 'Refund': {'code': 12, 'text': 'Order Refund Requested'}, + 'Refunded': {'code': 13, 'text': 'Order Refunded'} +}; + /** * create an empty order @@ -49,23 +64,25 @@ function createOrderTemplate (_inbound) _inbound.orderNumber = ''; _inbound.amount = 0; _inbound.items = []; - _inbound.status = 'Order Created'; + _inbound.status = JSON.stringify(orderStatus.Created); _inbound.created = new Date().toISOString(); + _inbound.cancelled = ''; _inbound.ordered = ''; _inbound.bought = ''; _inbound.dateBackordered = ''; _inbound.requestShipment = ''; _inbound.delivered = ''; + _inbound.delivering = ''; _inbound.disputeOpened = ''; _inbound.disputeResolved = ''; _inbound.orderRefunded = ''; _inbound.paymentRequested = ''; + _inbound.approved = ''; _inbound.paid = ''; _inbound.dispute = ''; _inbound.resolve = ''; _inbound.backorder = ''; _inbound.refund = ''; - _inbound.vendors = []; return(_inbound); } /** @@ -87,52 +104,19 @@ function addItems (_inbound) orderAmount= _inbound.amount; return (_inbound); } -/** - * find a vendor in an array - * @param {vendor_type} _string - type of vendor to find (e.g. 'supplier', 'shipper', etc.) - * @param {vendor_array} _vendorArray - vendor array from order - * @returns {$identifier} - returns the identifier if found else -1 - * @utility - */ -function getVendor(_string, _vendorArray) -{ - for (let each in _vendorArray) - {for (let _prop in JSON.parse(_vendorArray[each])) - {if (_prop === _string){return (JSON.parse(_vendorArray[each])[_string]);}}} - return(-1); -} - -describe('Finance Network', () => { - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { it('should be able to create an order', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the buyer const buyer = factory.newResource(NS, 'Buyer', buyerID); buyer.companyName = 'billybob computing'; @@ -141,6 +125,18 @@ describe('Finance Network', () => { const seller = factory.newResource(NS, 'Seller', sellerID); seller.companyName = 'Simon PC Hardware, Inc'; + // create the provider + provider = factory.newResource(NS, 'Provider', providerID); + provider.companyName = 'Ginsu Knife Specialists'; + + // create the shipper + shipper = factory.newResource(NS, 'Shipper', shipperID); + shipper.companyName = 'Fastest Ever Shippers'; + + // create the financeCo + financeCo = factory.newResource(NS, 'FinanceCo', financeCoID); + financeCo.companyName = 'The Global Financier'; + // create the order let order = factory.newResource(NS, 'Order', orderNo); order = createOrderTemplate(order); @@ -152,13 +148,17 @@ describe('Finance Network', () => { order.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier); order.seller = factory.newRelationship(NS, 'Seller', seller.$identifier); + order.provider = factory.newRelationship(NS, 'Provider', provider.$identifier); + order.shipper = factory.newRelationship(NS, 'Shipper', shipper.$identifier); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCo.$identifier); createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); createNew.buyer = factory.newRelationship(NS, 'Buyer', buyer.$identifier); createNew.seller = factory.newRelationship(NS, 'Seller', seller.$identifier); createNew.amount = order.amount; // the buyer should of the commodity should be buyer //order.buyer.$identifier.should.equal(buyer.$identifier); - order.status.should.equal('Order Created'); + JSON.parse(order.status).text.should.equal(orderStatus.Created.text); order.amount.should.equal(orderAmount); createNew.amount.should.equal(orderAmount); createNew.order.$identifier.should.equal(orderNo); @@ -174,7 +174,7 @@ describe('Finance Network', () => { }) .then((participantRegistry) => { // add the buyer and seller - return participantRegistry.addAll([buyer, seller]); + return participantRegistry.addAll([buyer, seller, shipper, provider]); }) .then(() => { // submit the transaction @@ -226,7 +226,7 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.buyer.$identifier.should.equal(buyerID); - newOrder.status.should.equal('Purchased'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Bought.text); }); }); @@ -238,18 +238,10 @@ describe('Finance Network', () => { it('should be able to issue a supplier order', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the provider - const provider = factory.newResource(NS, 'Provider', providerID); - provider.companyName = 'Ginsu Knife Specialists'; - // create the buy transaction const orderNow = factory.newTransaction(NS, 'OrderFromSupplier'); return businessNetworkConnection.getParticipantRegistry(NS + '.Provider') - .then((participantRegistry) => { - // add the provider - return participantRegistry.addAll([provider]); - }) .then(() => { return businessNetworkConnection.getAssetRegistry(NS + '.Order'); }) @@ -263,6 +255,7 @@ describe('Finance Network', () => { orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); orderNow.provider = factory.newRelationship(NS, 'Provider', providerID); + orderNow.seller = factory.newRelationship(NS, 'Seller', sellerID); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) .then(() => { @@ -274,9 +267,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('supplier', newOrder.vendors); - vendor.should.equal(providerID); - newOrder.status.should.equal('Ordered From Supplier'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Ordered.text); }); }); @@ -287,10 +278,6 @@ describe('Finance Network', () => { it('should be able to issue a request to ship product', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the shipper - const shipper = factory.newResource(NS, 'Shipper', shipperID); - shipper.companyName = 'Fastest Ever Shippers'; - // create the buy transaction const orderNow = factory.newTransaction(NS, 'RequestShipping'); @@ -311,6 +298,7 @@ describe('Finance Network', () => { newOrder.$identifier.should.equal(orderNo); orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); + orderNow.provider = factory.newRelationship(NS, 'Provider', providerID); orderNow.shipper = factory.newRelationship(NS, 'Shipper', shipperID); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) @@ -323,9 +311,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('shipper', newOrder.vendors); - vendor.should.equal(shipperID); - newOrder.status.should.equal('Shipment Requested'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.ShipRequest.text); }); }); @@ -361,9 +347,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('shipper', newOrder.vendors); - vendor.should.equal(shipperID); - newOrder.status.should.equal('Delivered'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Delivered.text); }); }); @@ -375,10 +359,6 @@ describe('Finance Network', () => { it('should be able to issue a request to request payment for a product', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - // create the financeCo - const financeCo = factory.newResource(NS, 'FinanceCo', financeCoID); - financeCo.companyName = 'The Global Financier'; - // create the buy transaction const orderNow = factory.newTransaction(NS, 'RequestPayment'); @@ -400,7 +380,6 @@ describe('Finance Network', () => { orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) @@ -413,17 +392,53 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('financeCo', newOrder.vendors); - vendor.should.equal(financeCoID); - newOrder.status.should.equal('Payment Requested'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.PayRequest.text); }); }); }); }); - describe('#issuePayment', () => { + describe('#authorizePayment', () => { - it('should be able to record a product payment', () => { + it('should be able to record a approval for order payment', () => { + const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + + // create the Deliver transaction + const orderNow = factory.newTransaction(NS, 'AuthorizePayment'); + + return businessNetworkConnection.getAssetRegistry(NS + '.Order') + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + newOrder.buyer.$identifier.should.equal(buyerID); + newOrder.$identifier.should.equal(orderNo); + + orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); + orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); + // submit the transaction + return businessNetworkConnection.submitTransaction(orderNow) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS + '.Order'); + }) + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + // the owner of the commodity should be buyer + JSON.parse(newOrder.status).text.should.equal(orderStatus.Authorize.text); + }); + + }); + }); + }); + + describe('#Pay', () => { + + it('should be able to record an order payment', () => { const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); // create the Deliver transaction @@ -452,9 +467,7 @@ describe('Finance Network', () => { }) .then((newOrder) => { // the owner of the commodity should be buyer - let vendor = getVendor('financeCo', newOrder.vendors); - vendor.should.equal(financeCoID); - newOrder.status.should.equal('Paid'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Paid.text); }); }); @@ -495,7 +508,7 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.dispute.should.equal(dispute); - newOrder.status.should.equal('In Dispute'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Dispute.text); }); }); @@ -523,6 +536,8 @@ describe('Finance Network', () => { orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); orderNow.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier); + orderNow.shipper = factory.newRelationship(NS, 'Shipper', newOrder.shipper.$identifier); + orderNow.provider = factory.newRelationship(NS, 'Provider', provider.$identifier); orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) @@ -536,7 +551,7 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.resolve.should.equal(resolve); - newOrder.status.should.equal('Resolved'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Resolve.text); }); }); @@ -562,7 +577,7 @@ describe('Finance Network', () => { orderNow.backorder = backorder; orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); - orderNow.provider = factory.newRelationship(NS, 'Provider', JSON.parse(newOrder.vendors[0]).supplier); + orderNow.provider = factory.newRelationship(NS, 'Provider', providerID); // submit the transaction return businessNetworkConnection.submitTransaction(orderNow) .then(() => { @@ -575,7 +590,44 @@ describe('Finance Network', () => { .then((newOrder) => { // the owner of the commodity should be buyer newOrder.backorder.should.equal(backorder); - newOrder.status.should.equal('Backordered'); + JSON.parse(newOrder.status).text.should.equal(orderStatus.Backordered.text); + }); + + }); + }); + }); + describe('#issueCancel', () => { + + it('should be able to record an order cancellation', () => { + const factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + + // create the Deliver transaction + const orderNow = factory.newTransaction(NS, 'OrderCancel'); + + return businessNetworkConnection.getAssetRegistry(NS + '.Order') + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + newOrder.buyer.$identifier.should.equal(buyerID); + newOrder.$identifier.should.equal(orderNo); + + orderNow.order = factory.newRelationship(NS, 'Order', newOrder.$identifier); + orderNow.seller = factory.newRelationship(NS, 'Seller', newOrder.seller.$identifier); + orderNow.buyer = factory.newRelationship(NS, 'Buyer', newOrder.buyer.$identifier); + // submit the transaction + return businessNetworkConnection.submitTransaction(orderNow) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS + '.Order'); + }) + .then((assetRegistry) => { + // re-get the commodity + return assetRegistry.get(orderNo); + }) + .then((newOrder) => { + // the owner of the commodity should be buyer + JSON.parse(newOrder.status).text.should.equal(orderStatus.Cancelled.text); }); }); diff --git a/Chapter04/package.json b/Chapter04/package.json index 1d086ff..57535e3 100644 --- a/Chapter04/package.json +++ b/Chapter04/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter04/shutdown.sh b/Chapter04/shutdown.sh index 3fb615d..f270d76 100755 --- a/Chapter04/shutdown.sh +++ b/Chapter04/shutdown.sh @@ -1,40 +1,11 @@ #!/bin/bash - YELLOW='\033[1;33m' - RED='\033[1;31m' - GREEN='\033[1;32m' - RESET='\033[0m' +. ../common_OSX.sh -# indent text on echo -function indent() { - c='s/^/ /' - case $(uname) in - Darwin) sed -l "$c";; - *) sed -u "$c";; - esac -} - -# Grab the current directory -function getCurrent() - { - showStep "getting current directory" - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - THIS_SCRIPT=`basename "$0"` - showStep "Running '${THIS_SCRIPT}'" - } - -# displays where we are, uses the indent function (above) to indent each line -function showStep () - { - echo -e "${YELLOW}=====================================================" | indent - echo -e "${RESET}-----> $*" | indent - echo -e "${YELLOW}=====================================================${RESET}" | indent - } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "stopping fabric" ./stopFabric.sh showStep "tear down" ./teardownFabric.sh -showStep "shut down complete"#!/bin/bash - \ No newline at end of file +showStep "shut down complete" \ No newline at end of file diff --git a/Chapter04/startup.sh b/Chapter04/startup.sh index b4c76e2..a4602d8 100755 --- a/Chapter04/startup.sh +++ b/Chapter04/startup.sh @@ -35,6 +35,12 @@ showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" ~/fabric-tools/startFabric.sh -showStep "creating new composer profile (required with each restart)" -~/fabric-tools/createComposerProfile.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter04/z2c_login b/Chapter04/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter04/z2c_login +++ b/Chapter04/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf index 09309b3..07b156c 100644 Binary files a/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf and b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pdf differ diff --git a/Chapter05/Documentation/Chinese/Z2B_Chapter05.pptx b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pptx new file mode 100644 index 0000000..0e74563 Binary files /dev/null and b/Chapter05/Documentation/Chinese/Z2B_Chapter05.pptx differ diff --git a/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf index 35e602a..0829563 100644 Binary files a/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf and b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pdf differ diff --git a/Chapter05/Documentation/Espanol/Z2B_Chapter05.pptx b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pptx new file mode 100644 index 0000000..1eaba4e Binary files /dev/null and b/Chapter05/Documentation/Espanol/Z2B_Chapter05.pptx differ diff --git a/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf index 15a25a3..dcebfa5 100644 Binary files a/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf and b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pdf differ diff --git a/Chapter05/Documentation/Japanese/Z2B_Chapter05.pptx b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pptx new file mode 100644 index 0000000..3226c0e Binary files /dev/null and b/Chapter05/Documentation/Japanese/Z2B_Chapter05.pptx differ diff --git a/Chapter05/Documentation/Z2B Chapter05.pdf b/Chapter05/Documentation/Z2B Chapter05.pdf index 1516823..7b51202 100644 Binary files a/Chapter05/Documentation/Z2B Chapter05.pdf and b/Chapter05/Documentation/Z2B Chapter05.pdf differ diff --git a/Chapter05/Documentation/answers/HTML/admin_complete.html b/Chapter05/Documentation/answers/HTML/admin_complete.html index a010464..53b3a2d 100644 --- a/Chapter05/Documentation/answers/HTML/admin_complete.html +++ b/Chapter05/Documentation/answers/HTML/admin_complete.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
- + \ No newline at end of file diff --git a/Chapter05/Documentation/answers/HTML/removeMember_complete.html b/Chapter05/Documentation/answers/HTML/removeMember_complete.html index 718b809..63adcf5 100644 --- a/Chapter05/Documentation/answers/HTML/removeMember_complete.html +++ b/Chapter05/Documentation/answers/HTML/removeMember_complete.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js b/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js index 27b12a3..8e9e8b9 100644 --- a/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js +++ b/Chapter05/Documentation/answers/composer/hlcAdmin_complete.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter05/Documentation/answers/js/z2b-admin_complete.js b/Chapter05/Documentation/answers/js/z2b-admin_complete.js index c716cb8..1ad3017 100644 --- a/Chapter05/Documentation/answers/js/z2b-admin_complete.js +++ b/Chapter05/Documentation/answers/js/z2b-admin_complete.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,47 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + { + // ========> Your Code Goes Here <========= + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + // ========> Your Code Goes Here <========= + }); } /** @@ -130,55 +116,48 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { + // ========> Your Code Goes Here <========= + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +165,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { + let _str = ''; + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +181,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { + let _str = ''; + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +197,14 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +213,22 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +236,13 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +251,22 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +274,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { + let _str = ''; + // ========> Your Code Goes Here <========= + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter05/HTML/CSS/pageStyles.css b/Chapter05/HTML/CSS/pageStyles.css index d6d67bf..6038b35 100755 --- a/Chapter05/HTML/CSS/pageStyles.css +++ b/Chapter05/HTML/CSS/pageStyles.css @@ -47,6 +47,17 @@ body {height: 100%} overflow: auto; } } +.strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: #5DC15D;} .provider { background-color: #8A99D3;} @@ -72,14 +83,14 @@ p.message{ } .scrollingPaneLeft{ position: fixed; - height: 85%; + height: 80%; margin-left: 1%; width: 45%; overflow: auto; } .scrollingPaneRight{ position: fixed; - height: 85%; + height: 80%; margin-left: 50%; width: 45%; overflow: auto; @@ -87,10 +98,10 @@ p.message{ .blockchain { background-color: black; position: fixed; - height: 9%; + height: 8%; margin-left: 1%; width: 95%; - top: 90%; + top: 92%; padding: 4px; overflow-x: auto; overflow-y: hidden; diff --git a/Chapter05/HTML/admin.html b/Chapter05/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter05/HTML/admin.html +++ b/Chapter05/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
-
+ \ No newline at end of file diff --git a/Chapter05/HTML/adminHelp.html b/Chapter05/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter05/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter05/HTML/js/z2b-admin.js b/Chapter05/HTML/js/z2b-admin.js index 569b294..67f421a 100644 --- a/Chapter05/HTML/js/z2b-admin.js +++ b/Chapter05/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,56 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -129,54 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -184,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -200,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -216,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -233,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -257,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -275,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -301,351 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History - */ - + */ function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter05/HTML/js/z2b-initiate.js b/Chapter05/HTML/js/z2b-initiate.js index b566a28..8f676be 100644 --- a/Chapter05/HTML/js/z2b-initiate.js +++ b/Chapter05/HTML/js/z2b-initiate.js @@ -46,8 +46,8 @@ var orderStatus = { { // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English goMultiLingual("US_English", "index"); - // memberLoad loads the members already present in the network + // singleUX loads the members already present in the network memberLoad(); - // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring - getChainEvents(); + // getChainEvents creates a web socket connection with the server and initiates blockchain event monitoring + getChainEvents(); } diff --git a/Chapter05/HTML/removeMember.html b/Chapter05/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter05/HTML/removeMember.html +++ b/Chapter05/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter05/buildAndDeploy b/Chapter05/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter05/buildAndDeploy +++ b/Chapter05/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter05/controller/env.json b/Chapter05/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter05/controller/env.json +++ b/Chapter05/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/composer/autoLoad.js b/Chapter05/controller/restapi/features/composer/autoLoad.js index 1f5214f..ce3d81b 100644 --- a/Chapter05/controller/restapi/features/composer/autoLoad.js +++ b/Chapter05/controller/restapi/features/composer/autoLoad.js @@ -14,62 +14,57 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/composer/hlcAdmin.js b/Chapter05/controller/restapi/features/composer/hlcAdmin.js index 7190361..03049e8 100644 --- a/Chapter05/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter05/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,51 +115,60 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. + * This method will be superceded in v0.17, possibly as early as v0.16, with adminConnection.start(), which will create the necessary + * business network admin id as part of the start process, in line with how the cli now operates * @param {express.req} req - the inbound request object from the client * req.body.myArchive: _string - string name of object * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - - let adminConnection = new composerAdmin.AdminConnection(); - - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + + let adminConnection = new composerAdmin.AdminConnection(); + + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,35 +176,31 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { - + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { - return adminConnection.install(businessNetworkDefinition.getName()) - .then(() => { - console.log('business network '+req.body.myArchive+' installed successful: '); - res.send({install: req.body.myArchive+' install succeeded'}); - }) - .catch((error) => { - console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); - res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + // ========> Your Code Goes Here <========= + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,29 +209,25 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { - + + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ - adminConnection.start(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' installed successful: '); - res.send({install: req.body.myArchive+' install succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' install failed: ',error); - res.send({install: error}); - }); - }); - }); - }; + // ========> Your Code Goes Here <========= + }); + }); +}; /** * disconnects this connection @@ -238,18 +239,13 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + // ========> Your Code Goes Here <========= + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +257,13 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + // ========> Your Code Goes Here <========= + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +276,13 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + // ========> Your Code Goes Here <========= + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,50 +294,15 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); + // updated to use PeerAdmin, PeerPW to work with V0.14 + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + // ========> Your Code Goes Here <========= + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -362,19 +314,13 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + // ========> Your Code Goes Here <========= + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -387,19 +333,13 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + // ========> Your Code Goes Here <========= + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -407,7 +347,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -418,21 +358,14 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + // ========> Your Code Goes Here <========= + }); }; /** @@ -440,7 +373,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -449,29 +382,16 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + // ========> Your Code Goes Here <========= + }) + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -479,66 +399,102 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + // ========> Your Code Goes Here <========= + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - -} + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; + +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => { + // ========> Your Code Goes Here <========= + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + // ========> Your Code Goes Here <========= + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + // ========> Your Code Goes Here <========= + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -547,87 +503,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) - { - switch(req.body.type) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) + { + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -637,38 +589,27 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + // ========> Your Code Goes Here <========= + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -677,38 +618,29 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + // ========> Your Code Goes Here <========= + }) + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -716,43 +648,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter05/controller/restapi/features/composer/hlcClient.js b/Chapter05/controller/restapi/features/composer/hlcClient.js index 03d9523..bc5bfb6 100644 --- a/Chapter05/controller/restapi/features/composer/hlcClient.js +++ b/Chapter05/controller/restapi/features/composer/hlcClient.js @@ -14,14 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const config = require('../../../env.json'); +const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -29,70 +29,83 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let newFile = path.join(path.dirname(require.main.filename),'network','package.json'); - let packageJSON = JSON.parse(fs.readFileSync(newFile)); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - let serializer; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} + let ser; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); - console.log('getMyOrders for user: '+req.body.userID+' with secret: '+req.body.secret); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + ser = bnd.getSerializer(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { return businessNetworkConnection.query('selectOrders') .then((orders) => { - console.log('there are '+orders.length+' orders for '+req.body.userID); - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); }) - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message});; - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); }) - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message});; - } + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); + res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); + }); +}; + /** * return a json object built from the item table created by the autoload function * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -102,156 +115,156 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} - console.log('req.body.orderNo is: ', req.body.orderNo); + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - updateOrder = factory.newTransaction(NS, 'Pay'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - console.log('participants: buyer: '+order.buyer.$identifier+' seller: '+order.seller.$identifier+' provider: '+order.provider.$identifier+' shipper: '+order.shipper.$identifier) - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message); - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + console.log('Pay entered'); + updateOrder = factory.newTransaction(NS, 'Pay'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + console.log('Update Delivery Status'); + updateOrder = factory.newTransaction(NS, 'Delivering'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + updateOrder.deliveryStatus = req.body.delivery; + break; + case 'Delivered': + console.log('Delivered entered'); + updateOrder = factory.newTransaction(NS, 'Deliver'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -260,83 +273,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - console.log(orderNo); - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - console.log(orderNo+" submitTransaction failed with text: ",error.message); - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - }); - }) - .catch((error) => { - console.log(orderNo+" assetRegistry.add failed: ",error.message); - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter05/controller/restapi/features/text/ch/prompts.json b/Chapter05/controller/restapi/features/text/ch/prompts.json index 363128d..5c6091d 100644 --- a/Chapter05/controller/restapi/features/text/ch/prompts.json +++ b/Chapter05/controller/restapi/features/text/ch/prompts.json @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", diff --git a/Chapter05/controller/restapi/features/text/en-UK/prompts.json b/Chapter05/controller/restapi/features/text/en-UK/prompts.json index 5a91a08..8f2be89 100644 --- a/Chapter05/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter05/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "UK English", - "title": "Z2B Chapter 5", - "header": "Chapter 5: Building the Administration User Experience", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 5", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 5. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 5: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 5, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 5, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 5, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 5", + "header":"Chapter 5: Building the Administrative User Experience", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/text/en-US/prompts.json b/Chapter05/controller/restapi/features/text/en-US/prompts.json index a4ab1f1..bc9e5c5 100644 --- a/Chapter05/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter05/controller/restapi/features/text/en-US/prompts.json @@ -1,219 +1,223 @@ { - "index": {"language": "US English", - "title": "Z2B Chapter 5", - "header": "Chapter 5: Building the Administration User Experience", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 5", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 5. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 5: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 5, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 5, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 5, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" + "index": {"language": "US English", + "title": "Z2B Chapter 5", + "header": "Chapter 5: Building the Administration User Experience", + "titleBar": "Zero to Blockchain Tutorial", + "idx_unified": "load Unified User Experience", + "idx_buyer": "load Buyer User Experience", + "idx_seller": "load Seller User Experience", + "idx_provider": "load Provider User Experience", + "idx_shipper": "load Shipper User Experience", + "idx_financeco": "load Finance Company User Experience", + "idx_roles": "Roles", + "idx_admin": "Admin", + "idx_adminUX": "load Admin User Experience", + "idx_preload": "Preload Network" + }, + "admin": { + "title": "Zero To Blockchain Chapter 5", + "npm": "Network Profile Management", + "npm_API": "API", + "npm_param": "Parameters", + "npm_dp_api": "delete profile", + "npm_dp_param": "profile name", + "npm_cp_api": "create Profile", + "npm_cp_param": "profile object", + "npm_ga_api": "get all connection profiles", + "npm_ga_param": "(none)", + "npm_g1_api": "get a specific network connection profile", + "npm_g1_param": "profile name", + "bnm": "Business Network Management", + "bnm_param": "Parameters", + "bnm_api": "API", + "bnm_nd_api": "deploy a network", + "bnm_nd_param": "network archive file, options", + "bnm_ni_api": "install new a network", + "bnm_ni_param": "network archive file, options", + "bnm_ns_api": "start an installed network", + "bnm_ns_param": "network name, options", + "bnm_nl_api": "list the deployed business networks", + "bnm_nl_param": "(none)", + "bnm_np_api": "touch a network, check compatibility", + "bnm_np_param": "business network name", + "bnm_nu_api": "take a business network off line", + "bnm_nu_param": "business network name<", + "bnm_nuu_api": "update an existing business network", + "bnm_nuu_param": "business network name, archive file", + "rm": "Resource Management", + "rm_api": "API", + "rm_param": "Parameters", + "rm_lr_api": "list members of a registry", + "rm_la_api": "List Assets in the registry", + "rm_la_param": "(none)", + "rm_am_api": "Add Member", + "rm_am_param": "Co Name, id, Type", + "rm_rm_api": "Remove Member", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", + "bc": "BlockChain", + "bc_api": "API", + "bc_param": "Parameters", + "bc_gi_api": "initiate connection to blockchain", + "bc_gi_param": "(none)", + "bc_ge_api": "register for blockchain events", + "bc_ge_param": "(none)", + "bc_gh_api": "get Historian", + "bc_gh_param": "(none)" + }, + "buyer": { + "title": "Buyer Chapter 5. Select Buyer to see their view: ", + "newOrder": "Create New Order", + "orderStatus": "Display Order Status" + }, + "createConnectionProfile": { + "title": "type the name of the new profile here: ", + "cp_type": "type", + "cp_orderers": "orderers", + "cp_orderers_url": "url", + "cp_ca": "ca", + "cp_ca_url": "url", + "cp_ca_name": "name", + "cp_peers": "peers", + "cp_peers_event_url": "eventURL", + "cp_peers_request_url": "requestURL", + "cp_keyValStore": "keyValStore", + "cp_channel": "channel", + "cp_mspID": "mspID", + "cp_timeout": "timeout", + "cancel": "Cancel", + "submit": "Submit" + }, + "createMember": { + "cd_type": "Type", + "cd_buyer": "Buyer", + "cd_seller": "Seller", + "cd_shipper": "Shipper", + "cd_provider": "Provider", + "cd_financeco": "FinanceCo", + "cd_cn": "Company Name", + "cd_e": "email Address", + "cancel": "Cancel", + "submit": "Submit" + }, + "createOrder": { + "title": "Create New Order", + "selectVendor": "Select Vendor: ", + "cn_on": "Order Number", + "cn_status": "Status", + "cn_date": "Date", + "cn_total": "Total", + "cn_selectItem": "Select Item", + "addItem": "Add Item", + "cancelNewOrder": "Cancel", + "submitNewOrder": "Submit" + }, + "deleteConnectionProfile": { + "title": "Select Profile to delete: ", + "cancel": "Cancel", + "submit": "Submit" + }, + "financeCo": { + "title": "Zero To Blockchain Chapter 5: The Global Financier", + "financeCOclear": "Clear Window", + "financeCOorderStatus": "Display Order Status" + }, + "getMemberSecret": { + "gs_type": "Type", + "gs_members": "Members", + "gs_company": "Company Name", + "gs_email": "email Address", + "gs_userID": "userID", + "gs_secret": "secret", + "cancel": "Cancel", + "submit": "Submit" + }, + "provider": { + "title": "Provider Chapter 5, Select Provider to see their view: ", + "provider_clear": "Clear Window", + "providerOrderStatus": "Display Order Status" + }, + "removeMember": { + "rm_type": "Type", + "rm_members": "Members", + "rm_company": "Company Name", + "rm_email": "email Address", + "rm_userID": "userID", + "rm_secret": "secret", + "cancel": "Cancel", + "submit": "Submit" + }, + "seller": { + "title": "Seller Chapter 5, Select Seller to see their view: ", + "seller_clear": "Clear Window", + "sellerOrderStatus": "Display Order Status" + }, + "shipper": { + "title": "Shipper Chapter 5, Select Shipper to see their view: ", + "shipper_clear": "Clear Window", + "shipperOrderStatus": "Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, + "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, + "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, + "Purchase": {"select": "Purchase", "message": "Purchase"}, + "Cancel": {"select": "Cancel", "message": "Cancel"}, + "Pay": {"select": "Pay", "message": "Pay"}, + "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, + "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, + "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, + "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, + "Delivered": {"select": "Delivered", "message": "Delivered"}, + "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, + "Order": {"select": "Order", "message": "Order From Supplier"}, + "NoAction": {"select": "NoAction", "message": "Take No Action"}, + "ex_button": "Execute", + "ca_button": "Cancel", + "orderno": "Order #", + "status": "Status", + "total": "Total", + "seller": "Seller: ", + "itemno": "Item Number", + "description": "Description", + "qty": "Quantity", + "price": "Price", + "processing_msg": "Processing {0} request for order number: {1}", + "b_no_order_msg": "No orders for this buyer: ", + "s_no_order_msg": "No orders for this seller: ", + "p_no_order_msg": "No orders for this provider: ", + "sh_no_order_msg": "No orders for this shipper: ", + "create_msg": "Processing Create Order request", + "buyer": "Buyer: " + }, + "financeCoOrder": { + "status": "Current Status: ", + "action": "Action", + "by": "By", + "date": "Date", + "comments": "Comments", + "created": "Created", + "cancelled": "Cancelled?", + "notCancel": "(not Cancelled)", + "purchased": "Purchased", + "noPurchase": "(no Purchase Request)", + "thirdParty": "3rd Party Order", + "nothirdParty": "(not yet sent to 3rd Party)", + "backordered": "Backordered?", + "notBackordered": "(not Backordered)", + "shippingRequested": "Shipping Requested", + "noRequestShip": "(No Request to Shipper)", + "shippingStarted": "Shipping Started", + "noDeliveryStart": "(Delivery not Started)", + "delivered": "Delivered", + "notDelivered": "(not yet Delivered)", + "payRequested": "Payment Requested", + "noRequest": "(no request for payment)", + "disputed": "Dispute Raised", + "noDispute": "(not in Dispute)" + } } -} + \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/text/es-LA/prompts.json b/Chapter05/controller/restapi/features/text/es-LA/prompts.json index 59afa66..ec3dfb4 100644 --- a/Chapter05/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter05/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 5", - "header":"Capítulo 5: Construyendo la experiencia del usuario administrativa", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 5", + "header":"Capítulo 5: Construyendo la experiencia del usuario administrativa", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/text/fr/prompts.json b/Chapter05/controller/restapi/features/text/fr/prompts.json index 646429e..fba1a48 100644 --- a/Chapter05/controller/restapi/features/text/fr/prompts.json +++ b/Chapter05/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 05", - "header":"Chapitre 05 : Construire l'experience de l'administrateur", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 05", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 5", + "header":"Chapitre 5 : Construire l'experience de l'administrateur", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { "title":"Zero to Blockchain Chapitre 10: Le financier mondial", "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer{0} demander le numero de commande:{1}", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/text/jp/prompts.json b/Chapter05/controller/restapi/features/text/jp/prompts.json index eadeb56..34a6a9e 100644 --- a/Chapter05/controller/restapi/features/text/jp/prompts.json +++ b/Chapter05/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 5章", - "header":"弟 5章: 管理ユーザー経験の構築", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟05章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟07章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 5章", + "header":"弟 5章: 管理ユーザー経験の構築", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/text/languages.json b/Chapter05/controller/restapi/features/text/languages.json index 91b0348..8ee6b21 100644 --- a/Chapter05/controller/restapi/features/text/languages.json +++ b/Chapter05/controller/restapi/features/text/languages.json @@ -6,6 +6,6 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, - "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} + "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } \ No newline at end of file diff --git a/Chapter05/controller/restapi/features/text/pt/prompts.json b/Chapter05/controller/restapi/features/text/pt/prompts.json index 4a3c1db..7b6427e 100644 --- a/Chapter05/controller/restapi/features/text/pt/prompts.json +++ b/Chapter05/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 5", + "header":"Capítulo 5: Construindo a Experiência de Usuário Administrativo", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter05/controller/restapi/router.js b/Chapter05/controller/restapi/router.js index 02b3d35..a8e73d8 100644 --- a/Chapter05/controller/restapi/router.js +++ b/Chapter05/controller/restapi/router.js @@ -69,7 +69,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -86,3 +85,7 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); + diff --git a/Chapter05/createArchive.sh b/Chapter05/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter05/createArchive.sh +++ b/Chapter05/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter05/deployNetwork.sh b/Chapter05/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter05/deployNetwork.sh +++ b/Chapter05/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter05/favicon.ico b/Chapter05/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter05/favicon.ico and b/Chapter05/favicon.ico differ diff --git a/Chapter05/network/package.json b/Chapter05/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter05/network/package.json +++ b/Chapter05/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter05/network/test/sample.js b/Chapter05/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter05/network/test/sample.js +++ b/Chapter05/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter05/package.json b/Chapter05/package.json index 1d086ff..57535e3 100644 --- a/Chapter05/package.json +++ b/Chapter05/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter05/startup.sh b/Chapter05/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter05/startup.sh +++ b/Chapter05/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter05/z2c_login b/Chapter05/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter05/z2c_login +++ b/Chapter05/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf index 2f58874..9dfa9a0 100644 Binary files a/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf and b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pdf differ diff --git a/Chapter06/Documentation/Chinese/Z2B_Chapter06.pptx b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pptx new file mode 100644 index 0000000..3630baf Binary files /dev/null and b/Chapter06/Documentation/Chinese/Z2B_Chapter06.pptx differ diff --git a/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf index a8d82db..74689e3 100644 Binary files a/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf and b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pdf differ diff --git a/Chapter06/Documentation/Espanol/Z2B_Chapter06.pptx b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pptx new file mode 100644 index 0000000..fa4edc1 Binary files /dev/null and b/Chapter06/Documentation/Espanol/Z2B_Chapter06.pptx differ diff --git a/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf index 8167b45..333f236 100644 Binary files a/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf and b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pdf differ diff --git a/Chapter06/Documentation/Japanese/Z2B_Chapter06.pptx b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pptx new file mode 100644 index 0000000..97e3365 Binary files /dev/null and b/Chapter06/Documentation/Japanese/Z2B_Chapter06.pptx differ diff --git a/Chapter06/Documentation/Z2B Chapter06.pdf b/Chapter06/Documentation/Z2B Chapter06.pdf index eaee625..3dab8b9 100644 Binary files a/Chapter06/Documentation/Z2B Chapter06.pdf and b/Chapter06/Documentation/Z2B Chapter06.pdf differ diff --git a/Chapter06/Documentation/answers/composer/hlcClient_complete.js b/Chapter06/Documentation/answers/composer/hlcClient_complete.js index 401bf01..00e58c9 100644 --- a/Chapter06/Documentation/answers/composer/hlcClient_complete.js +++ b/Chapter06/Documentation/answers/composer/hlcClient_complete.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,155 +115,130 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - updateOrder = factory.newTransaction(NS, 'Pay'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + + break; + case 'Request Payment': + + break; + case 'Refund': + + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + break; + case 'Update Delivery Status': + break; + case 'Delivered': + + break; + case 'BackOrder': + + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -268,85 +247,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter06/Documentation/answers/js/z2b-buyer_complete.js b/Chapter06/Documentation/answers/js/z2b-buyer_complete.js index 37f4b2c..535f938 100644 --- a/Chapter06/Documentation/answers/js/z2b-buyer_complete.js +++ b/Chapter06/Documentation/answers/js/z2b-buyer_complete.js @@ -14,166 +14,173 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; +'use strict'; + +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#body").empty(); - $("#body").append(page); - // update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#body').empty(); + $('#body').append(page); + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() { _orderDiv.empty(); $("#buyer_messages").empty(); $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; }); + $('#company')[0].innerText = buyers[0].companyName; + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array @@ -183,113 +190,114 @@ function listOrders() */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + })(each, _orders) + } } \ No newline at end of file diff --git a/Chapter06/HTML/CSS/pageStyles.css b/Chapter06/HTML/CSS/pageStyles.css index d6d67bf..6038b35 100755 --- a/Chapter06/HTML/CSS/pageStyles.css +++ b/Chapter06/HTML/CSS/pageStyles.css @@ -47,6 +47,17 @@ body {height: 100%} overflow: auto; } } +.strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: #5DC15D;} .provider { background-color: #8A99D3;} @@ -72,14 +83,14 @@ p.message{ } .scrollingPaneLeft{ position: fixed; - height: 85%; + height: 80%; margin-left: 1%; width: 45%; overflow: auto; } .scrollingPaneRight{ position: fixed; - height: 85%; + height: 80%; margin-left: 50%; width: 45%; overflow: auto; @@ -87,10 +98,10 @@ p.message{ .blockchain { background-color: black; position: fixed; - height: 9%; + height: 8%; margin-left: 1%; width: 95%; - top: 90%; + top: 92%; padding: 4px; overflow-x: auto; overflow-y: hidden; diff --git a/Chapter06/HTML/admin.html b/Chapter06/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter06/HTML/admin.html +++ b/Chapter06/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
-
+ \ No newline at end of file diff --git a/Chapter06/HTML/adminHelp.html b/Chapter06/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter06/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter06/HTML/createOrder.html b/Chapter06/HTML/createOrder.html index cc1a0dc..e5e57bd 100644 --- a/Chapter06/HTML/createOrder.html +++ b/Chapter06/HTML/createOrder.html @@ -2,10 +2,11 @@

- + +
- +
diff --git a/Chapter06/HTML/favicon.ico b/Chapter06/HTML/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter06/HTML/favicon.ico and b/Chapter06/HTML/favicon.ico differ diff --git a/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf index 1413fc6..1f85312 100644 Binary files a/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter06/HTML/fonts/glyphicons-halflings-regular.ttf differ diff --git a/Chapter06/HTML/icons/Search.ico b/Chapter06/HTML/icons/Search.ico index e1d39ae..fd437a0 100755 Binary files a/Chapter06/HTML/icons/Search.ico and b/Chapter06/HTML/icons/Search.ico differ diff --git a/Chapter06/HTML/js/z2b-admin.js b/Chapter06/HTML/js/z2b-admin.js index c716cb8..67f421a 100644 --- a/Chapter06/HTML/js/z2b-admin.js +++ b/Chapter06/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -130,55 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter06/HTML/js/z2b-buyer.js b/Chapter06/HTML/js/z2b-buyer.js index 31007b3..c91fdd5 100644 --- a/Chapter06/HTML/js/z2b-buyer.js +++ b/Chapter06/HTML/js/z2b-buyer.js @@ -14,142 +14,179 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; +'use strict'; + +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#body").empty(); - $("#body").append(page); - // update the text on the page using the prompt data for the selected language - - // connect to the web socket and tell the web socket where to display messages + // empty the hetml element that will hold this page - // enable the buttons to process an onClick event + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages - // build the buer select HTML element + // enable the buttons to process an onClick event - // display the name of the current buyer + // build the buyer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } + // display the name of the current buyer - // create a function to execute when the user selects a different buyer + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; }); - } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - - // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call - - // build a select list for the items - - // hide the submit new order function until an item has been selected - - // create a new function to create an order when the order button is clicked - - // function to call when an item has been selected - - // remove the just selected item so that it cannot be added twice. - - // build a new item detail row in the display window - - // set the initial item count to 1 - - // set the initial price to the price of one item - - // add an entry into an array for this newly added item - - // update the order amount with this new item - - // function to update item detail row and total amount if itemm count is changed - }); - - } +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + + // update the page with the appropriate text for the selected language + + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + + // build a select list for the items + + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { + // remove the just selected item so that it cannot be added twice. + + // build a new item detail row in the display window + + // set the initial item count to 1 + + // set the initial price to the price of one item + + // add an entry into an array for this newly added item + + // update the order amount with this new item + + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); +} /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - - // get their orders - - // if they have no orders, then display a message to that effect - - // if they have orders, format and display the orders. - + let options = {}; + // get the users email address + + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { + // get their orders + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; + $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: break; @@ -187,35 +224,43 @@ function formatOrders(_target, _orders) break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); }); - })(each, _orders) - } + })(each, _orders) + } } \ No newline at end of file diff --git a/Chapter06/HTML/js/z2b-events.js b/Chapter06/HTML/js/z2b-events.js index f93de96..1b67217 100644 --- a/Chapter06/HTML/js/z2b-events.js +++ b/Chapter06/HTML/js/z2b-events.js @@ -58,6 +58,7 @@ function deferredMemberLoad() $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) { + console.log('buyers: ',_buyers); buyers = _buyers[0].members; sellers = _sellers[0].members; s_string = _getMembers(sellers); diff --git a/Chapter06/HTML/js/z2b-initiate.js b/Chapter06/HTML/js/z2b-initiate.js index b566a28..290ef03 100644 --- a/Chapter06/HTML/js/z2b-initiate.js +++ b/Chapter06/HTML/js/z2b-initiate.js @@ -46,7 +46,7 @@ var orderStatus = { { // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English goMultiLingual("US_English", "index"); - // memberLoad loads the members already present in the network + // singleUX loads the members already present in the network memberLoad(); // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring getChainEvents(); diff --git a/Chapter06/HTML/removeMember.html b/Chapter06/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter06/HTML/removeMember.html +++ b/Chapter06/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter06/buildAndDeploy b/Chapter06/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter06/buildAndDeploy +++ b/Chapter06/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter06/controller/env.json b/Chapter06/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter06/controller/env.json +++ b/Chapter06/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter06/controller/restapi/features/composer/autoLoad.js b/Chapter06/controller/restapi/features/composer/autoLoad.js index 1f5214f..ce3d81b 100644 --- a/Chapter06/controller/restapi/features/composer/autoLoad.js +++ b/Chapter06/controller/restapi/features/composer/autoLoad.js @@ -14,62 +14,57 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter06/controller/restapi/features/composer/hlcAdmin.js b/Chapter06/controller/restapi/features/composer/hlcAdmin.js index 27b12a3..8e9e8b9 100644 --- a/Chapter06/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter06/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter06/controller/restapi/features/composer/hlcClient.js b/Chapter06/controller/restapi/features/composer/hlcClient.js index d5df87c..0438465 100644 --- a/Chapter06/controller/restapi/features/composer/hlcClient.js +++ b/Chapter06/controller/restapi/features/composer/hlcClient.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,90 +115,91 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Dispute': - console.log('Dispute entered'); - - break; - case 'Purchase': - console.log('Purchase entered'); - - break; - case 'Resolve': - console.log('Resolve entered'); - - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - - break; - case 'Cancel': - console.log('Cancel entered'); - - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Dispute': + console.log('Dispute entered'); + // ========> Your Code Goes Here <========= + break; + case 'Purchase': + console.log('Purchase entered'); + // ========> Your Code Goes Here <========= + break; + case 'Resolve': + console.log('Resolve entered'); + // ========> Your Code Goes Here <========= + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + // ========> Your Code Goes Here <========= + break; + case 'Cancel': + console.log('Cancel entered'); + // ========> Your Code Goes Here <========= + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -203,85 +208,70 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + // ========> Your Code Goes Here <========= + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter06/controller/restapi/features/text/ch/prompts.json b/Chapter06/controller/restapi/features/text/ch/prompts.json index b9f6a49..97cabf4 100644 --- a/Chapter06/controller/restapi/features/text/ch/prompts.json +++ b/Chapter06/controller/restapi/features/text/ch/prompts.json @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", diff --git a/Chapter06/controller/restapi/features/text/en-UK/prompts.json b/Chapter06/controller/restapi/features/text/en-UK/prompts.json index d6ef84f..f8cd2b2 100644 --- a/Chapter06/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter06/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "UK English", - "title": "Z2B Chapter 6", - "header": "Chapter 6: Building the Buyer User Experience", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 6", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 6. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 6: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 6, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 6, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 6, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 6", + "header":"Chapter 6: Building the Buyer User Experience", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter06/controller/restapi/features/text/en-US/prompts.json b/Chapter06/controller/restapi/features/text/en-US/prompts.json index 1026a23..e8418e8 100644 --- a/Chapter06/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter06/controller/restapi/features/text/en-US/prompts.json @@ -53,7 +53,10 @@ "rm_am_api": "Add Member", "rm_am_param": "Co Name, id, Type", "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", "bc": "BlockChain", "bc_api": "API", "bc_param": "Parameters", @@ -96,8 +99,8 @@ "cd_financeco": "FinanceCo", "cd_cn": "Company Name", "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" + "cancel": "Cancel", + "submit": "Submit" }, "createOrder": { "title": "Create New Order", diff --git a/Chapter06/controller/restapi/features/text/es-LA/prompts.json b/Chapter06/controller/restapi/features/text/es-LA/prompts.json index e8b5220..0f915ae 100644 --- a/Chapter06/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter06/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 6", - "header":"Capítulo 6: Construyendo la experiencia del usuario del comprador", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 6", + "header":"Capítulo 6: Construyendo la experiencia del usuario del comprador", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter06/controller/restapi/features/text/fr/prompts.json b/Chapter06/controller/restapi/features/text/fr/prompts.json index e152842..794db18 100644 --- a/Chapter06/controller/restapi/features/text/fr/prompts.json +++ b/Chapter06/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 06", - "header":"Chapitre 06 : Construire l'experience de l'acheteur", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 06", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 6", + "header":"Chapitre 6 : Construire l'experience de l'acheteur", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { "title":"Zero to Blockchain Chapitre 10: Le financier mondial", "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer{0} demander le numero de commande:{1}", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter06/controller/restapi/features/text/jp/prompts.json b/Chapter06/controller/restapi/features/text/jp/prompts.json index c7f3c26..76fb476 100644 --- a/Chapter06/controller/restapi/features/text/jp/prompts.json +++ b/Chapter06/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 6章", - "header":"弟 6章: 購入者ユーザー経験の構築", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟05章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟07章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 6章", + "header":"弟 6章: 購入者ユーザー経験の構築", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter06/controller/restapi/features/text/languages.json b/Chapter06/controller/restapi/features/text/languages.json index 91b0348..8ee6b21 100644 --- a/Chapter06/controller/restapi/features/text/languages.json +++ b/Chapter06/controller/restapi/features/text/languages.json @@ -6,6 +6,6 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, - "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} + "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } \ No newline at end of file diff --git a/Chapter06/controller/restapi/features/text/pt/prompts.json b/Chapter06/controller/restapi/features/text/pt/prompts.json index 4a3c1db..11311d1 100644 --- a/Chapter06/controller/restapi/features/text/pt/prompts.json +++ b/Chapter06/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 6", + "header":"Capítulo 6: Construindo a Experiência de Usuário Consumidor", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter06/controller/restapi/router.js b/Chapter06/controller/restapi/router.js index dad4fa2..6fa15bd 100644 --- a/Chapter06/controller/restapi/router.js +++ b/Chapter06/controller/restapi/router.js @@ -12,18 +12,19 @@ * limitations under the License. */ +'use strict'; -var express = require('express'); -var router = express.Router(); -var format = require('date-format'); +let express = require('express'); +let router = express.Router(); +let format = require('date-format'); -var multi_lingual = require('./features/multi_lingual'); -var resources = require('./features/resources'); -var getCreds = require('./features/getCredentials'); -var hlcAdmin = require('./features/composer/hlcAdmin'); -var hlcClient = require('./features/composer/hlcClient'); -var setup = require('./features/composer/autoLoad'); -var hlcFabric = require('./features/composer/queryBlockChain'); +let multi_lingual = require('./features/multi_lingual'); +let resources = require('./features/resources'); +let getCreds = require('./features/getCredentials'); +let hlcAdmin = require('./features/composer/hlcAdmin'); +let hlcClient = require('./features/composer/hlcClient'); +let setup = require('./features/composer/autoLoad'); +let hlcFabric = require('./features/composer/queryBlockChain'); router.post('/setup/autoLoad*', setup.autoLoad); router.get('/setup/getPort*', setup.getPort); @@ -32,28 +33,28 @@ router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); router.get('/fabric/getHistory', hlcAdmin.getHistory); module.exports = router; -var count = 0; +let count = 0; /** - * This is a request tracking function which logs to the terminal window each request coming in to the web serve and + * This is a request tracking function which logs to the terminal window each request coming in to the web serve and * increments a counter to allow the requests to be sequenced. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ router.use(function(req, res, next) { - count++; - console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); - next(); // make sure we go to the next routes and don't stop here + count++; + console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); + next(); // make sure we go to the next routes and don't stop here }); // the following get and post statements tell nodeJS what to do when a request comes in -// The request is the single quoted phrase following the get( or post( statement. +// The request is the single quoted phrase following the get( or post( statement. // the text at the end identifies which function in which require(d) module to implement -// These are searched in order by get/post request. +// These are searched in order by get/post request. // The asterisk (*) means 'ignore anything following this point' -// which means we have to be careful about ordering these statements. +// which means we have to be careful about ordering these statements. // router.get('/api/getSupportedLanguages*',multi_lingual.languages); router.get('/api/getTextLocations*',multi_lingual.locations); @@ -69,7 +70,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -86,6 +86,9 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); // router requests specific to the Buyer router.get('/composer/client/getItemTable*', hlcClient.getItemTable); diff --git a/Chapter06/createArchive.sh b/Chapter06/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter06/createArchive.sh +++ b/Chapter06/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter06/deployNetwork.sh b/Chapter06/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter06/deployNetwork.sh +++ b/Chapter06/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter06/favicon.ico b/Chapter06/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter06/favicon.ico and b/Chapter06/favicon.ico differ diff --git a/Chapter06/network/dist/networkadmin.card b/Chapter06/network/dist/networkadmin.card new file mode 100644 index 0000000..7238f6d Binary files /dev/null and b/Chapter06/network/dist/networkadmin.card differ diff --git a/Chapter06/network/package.json b/Chapter06/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter06/network/package.json +++ b/Chapter06/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter06/network/test/sample.js b/Chapter06/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter06/network/test/sample.js +++ b/Chapter06/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter06/package.json b/Chapter06/package.json index 1d086ff..57535e3 100644 --- a/Chapter06/package.json +++ b/Chapter06/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter06/startup.sh b/Chapter06/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter06/startup.sh +++ b/Chapter06/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter06/z2c_login b/Chapter06/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter06/z2c_login +++ b/Chapter06/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf index 789736e..b7a141a 100644 Binary files a/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf and b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pdf differ diff --git a/Chapter07/Documentation/Chinese/Z2B_Chapter07.pptx b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pptx new file mode 100644 index 0000000..06a1e0a Binary files /dev/null and b/Chapter07/Documentation/Chinese/Z2B_Chapter07.pptx differ diff --git a/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf index fdf9240..357fbcf 100644 Binary files a/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf and b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pdf differ diff --git a/Chapter07/Documentation/Espanol/Z2B_Chapter07.pptx b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pptx new file mode 100644 index 0000000..5b44792 Binary files /dev/null and b/Chapter07/Documentation/Espanol/Z2B_Chapter07.pptx differ diff --git a/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf index 62aa4a8..917e26c 100644 Binary files a/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf and b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pdf differ diff --git a/Chapter07/Documentation/Japanese/Z2B_Chapter07.pptx b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pptx new file mode 100644 index 0000000..ecba27d Binary files /dev/null and b/Chapter07/Documentation/Japanese/Z2B_Chapter07.pptx differ diff --git a/Chapter07/Documentation/Z2B Chapter07.pdf b/Chapter07/Documentation/Z2B Chapter07.pdf index b71c481..d04cad7 100644 Binary files a/Chapter07/Documentation/Z2B Chapter07.pdf and b/Chapter07/Documentation/Z2B Chapter07.pdf differ diff --git a/Chapter07/Documentation/answers/composer/hlcClient_complete.js b/Chapter07/Documentation/answers/composer/hlcClient_complete.js index 1c43f70..d484aa5 100644 --- a/Chapter07/Documentation/answers/composer/hlcClient_complete.js +++ b/Chapter07/Documentation/answers/composer/hlcClient_complete.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,145 +115,141 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); + break; + case 'Update Delivery Status': - break; - case 'Delivered': - console.log('Delivered entered'); + break; + case 'Delivered': - break; - case 'BackOrder': - console.log('BackOrder entered'); - - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); + break; + case 'BackOrder': + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -258,85 +258,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter07/Documentation/answers/js/z2b-seller_complete.js b/Chapter07/Documentation/answers/js/z2b-seller_complete.js index 7099a9b..ecc7209 100644 --- a/Chapter07/Documentation/answers/js/z2b-seller_complete.js +++ b/Chapter07/Documentation/answers/js/z2b-seller_complete.js @@ -13,167 +13,171 @@ */ // z2c-seller.js -var sellerOrderDiv = "sellerOrderDiv"; + +'use strict'; +let sellerOrderDiv = 'sellerOrderDiv'; /** - * load the administration User Experience + * load the administration Seller Experience */ function loadSellerUX () { - toLoad = "seller.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupSeller(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'seller.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupSeller(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupSeller(page[0], port[0]);}); + } } +/** + * load the administration User Experience + * @param {String} page - page to load + * @param {Integer} port - web socket port to use + */ function setupSeller(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("seller"); - msgPort = port.port; - wsDisplay('seller_messages', msgPort); - var _clear = $("#seller_clear"); - var _list = $("#sellerOrderStatus"); - var _orderDiv = $("#"+sellerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - // - // this section changes from the previous chapter, buyer changing to seller - // - _list.on('click', function(){listSellerOrders()}); - $("#seller").empty(); - $("#seller").append(s_string); - $("#sellerCompany").empty(); - $("#sellerCompany").append(sellers[0].companyName); - $("#seller").on('change', function() { - $("#sellerCompany").empty(); _orderDiv.empty(); $("#seller_messages").empty(); - $("#sellerCompany").append(findMember($("#seller").find(":selected").val(),sellers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('seller'); + msgPort = port.port; + wsDisplay('seller_messages', msgPort); + let _clear = $('#seller_clear'); + let _list = $('#sellerOrderStatus'); + let _orderDiv = $('#'+sellerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + // + // this section changes from the previous chapter, buyer changing to seller + // + _list.on('click', function(){listSellerOrders();}); + $('#seller').empty(); + $('#seller').append(s_string); + $('#sellerCompany').empty(); + $('#sellerCompany').append(sellers[0].companyName); + $('#seller').on('change', function() { + $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty(); + $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName); + }); } /** * lists all orders for the selected seller */ function listSellerOrders() { - var options = {}; - // - // seller instead of buyer - // - options.id = $("#seller").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + // + // seller instead of buyer + // + options.id= $('#seller').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} - else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)} - }); - }); + { + if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} + else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);} + }); } /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatSellerOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += ''; - break; + _date = _arr[_idx].bought; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - var _string = '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + let _string = '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - - _target.append(_str); - for (let each in _orders) + + _target.append(_str); + for (let each in _orders) {(function(_idx, _arr) - { $("#s_btn_"+_idx).on('click', function () + { $('#s_btn_'+_idx).on('click', function () { - var options = {}; - options.action = $("#s_action"+_idx).find(":selected").text(); - options.orderNo = $("#s_order"+_idx).text(); - options.participant = $("#seller").val(); - options.provider = $("#providers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#s_reason"+_idx).val();} - $("#seller_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + let options = {}; + options.action = $('#s_action'+_idx).find(':selected').text(); + options.orderNo = $('#s_order'+_idx).text(); + options.participant = $('#seller').val(); + options.provider = $('#providers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#s_reason'+_idx).val();} + $('#seller_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#seller_messages").prepend(formatMessage(_results.result)); }); + { $('#seller_messages').prepend(formatMessage(_results.result)); }); }); - })(each, _orders) - } + })(each, _orders); + } } \ No newline at end of file diff --git a/Chapter07/HTML/CSS/pageStyles.css b/Chapter07/HTML/CSS/pageStyles.css index d6d67bf..6038b35 100755 --- a/Chapter07/HTML/CSS/pageStyles.css +++ b/Chapter07/HTML/CSS/pageStyles.css @@ -47,6 +47,17 @@ body {height: 100%} overflow: auto; } } +.strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: #5DC15D;} .provider { background-color: #8A99D3;} @@ -72,14 +83,14 @@ p.message{ } .scrollingPaneLeft{ position: fixed; - height: 85%; + height: 80%; margin-left: 1%; width: 45%; overflow: auto; } .scrollingPaneRight{ position: fixed; - height: 85%; + height: 80%; margin-left: 50%; width: 45%; overflow: auto; @@ -87,10 +98,10 @@ p.message{ .blockchain { background-color: black; position: fixed; - height: 9%; + height: 8%; margin-left: 1%; width: 95%; - top: 90%; + top: 92%; padding: 4px; overflow-x: auto; overflow-y: hidden; diff --git a/Chapter07/HTML/admin.html b/Chapter07/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter07/HTML/admin.html +++ b/Chapter07/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
-
+ \ No newline at end of file diff --git a/Chapter07/HTML/adminHelp.html b/Chapter07/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter07/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter07/HTML/favicon.ico b/Chapter07/HTML/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter07/HTML/favicon.ico and b/Chapter07/HTML/favicon.ico differ diff --git a/Chapter07/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter07/HTML/fonts/glyphicons-halflings-regular.ttf index 1413fc6..1f85312 100644 Binary files a/Chapter07/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter07/HTML/fonts/glyphicons-halflings-regular.ttf differ diff --git a/Chapter07/HTML/icons/Search.ico b/Chapter07/HTML/icons/Search.ico index e1d39ae..fd437a0 100755 Binary files a/Chapter07/HTML/icons/Search.ico and b/Chapter07/HTML/icons/Search.ico differ diff --git a/Chapter07/HTML/js/z2b-admin.js b/Chapter07/HTML/js/z2b-admin.js index c716cb8..67f421a 100644 --- a/Chapter07/HTML/js/z2b-admin.js +++ b/Chapter07/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -130,55 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter07/HTML/js/z2b-buyer.js b/Chapter07/HTML/js/z2b-buyer.js index 37f4b2c..535f938 100644 --- a/Chapter07/HTML/js/z2b-buyer.js +++ b/Chapter07/HTML/js/z2b-buyer.js @@ -14,166 +14,173 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; +'use strict'; + +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#body").empty(); - $("#body").append(page); - // update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#body').empty(); + $('#body').append(page); + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() { _orderDiv.empty(); $("#buyer_messages").empty(); $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; }); + $('#company')[0].innerText = buyers[0].companyName; + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array @@ -183,113 +190,114 @@ function listOrders() */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + })(each, _orders) + } } \ No newline at end of file diff --git a/Chapter07/HTML/js/z2b-events.js b/Chapter07/HTML/js/z2b-events.js index f93de96..3da467d 100644 --- a/Chapter07/HTML/js/z2b-events.js +++ b/Chapter07/HTML/js/z2b-events.js @@ -14,71 +14,76 @@ // z2c-events.js +'use strict'; + /** * load all of the members in the network for use in the different user experiences. This is a synchronous routine and is executed autormatically on web app start. * However, if this is a newly created network, then there are no members to retrieve and this will create four empty arrays */ function memberLoad () { - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = _buyers[0].members; - sellers = _sellers[0].members; - s_string = _getMembers(sellers); - providers = _providers[0].members - p_string = _getMembers(providers); - shippers = _shippers[0].members - sh_string = _getMembers(shippers); - }); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = _buyers[0].members; + sellers = _sellers[0].members; + s_string = _getMembers(sellers); + providers = _providers[0].members; + p_string = _getMembers(providers); + shippers = _shippers[0].members; + sh_string = _getMembers(shippers); + }); } + /** * load all of the members in the network for use in the different user experiences. This routine is designed for use if the network has been newly deployed and the web app was * started before the autoLoad function was run on the newly deployed network (which, by default, is empty). + * @returns {Promise} - promise upon completino of loadding member objects. */ function deferredMemberLoad() { - var d_prompts = $.Deferred(); - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = _buyers[0].members; - sellers = _sellers[0].members; - s_string = _getMembers(sellers); - providers = _providers[0].members - p_string = _getMembers(providers); - shippers = _shippers[0].members - sh_string = _getMembers(shippers); - d_prompts.resolve(); - }).fail(d_prompts.reject); - return d_prompts.promise(); + let d_prompts = $.Deferred(); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = _buyers[0].members; + sellers = _sellers[0].members; + s_string = _getMembers(sellers); + providers = _providers[0].members; + p_string = _getMembers(providers); + shippers = _shippers[0].members; + sh_string = _getMembers(shippers); + d_prompts.resolve(); + }).fail(d_prompts.reject); + return d_prompts.promise(); } /** * return an option list for use in an HTML '; - return _str; + return _str; } \ No newline at end of file diff --git a/Chapter07/HTML/js/z2b-initiate.js b/Chapter07/HTML/js/z2b-initiate.js index b566a28..bc5076a 100644 --- a/Chapter07/HTML/js/z2b-initiate.js +++ b/Chapter07/HTML/js/z2b-initiate.js @@ -13,41 +13,44 @@ */ // z2c-initiate.js -var connectionProfileName = "z2b-test-profile"; -var networkFile = "zerotoblockchain-network.bna" -var businessNetwork = "zerotoblockchain-network"; -var buyers, sellers, providers, shippers; -var s_string, p_string, sh_string; +'use strict'; -var orderStatus = { - Created: {code: 1, text: 'Order Created'}, - Bought: {code: 2, text: 'Order Purchased'}, - Cancelled: {code: 3, text: 'Order Cancelled'}, - Ordered: {code: 4, text: 'Order Submitted to Provider'}, - ShipRequest: {code: 5, text: 'Shipping Requested'}, - Delivered: {code: 6, text: 'Order Delivered'}, - Delivering: {code: 15, text: 'Order being Delivered'}, - Backordered: {code: 7, text: 'Order Backordered'}, - Dispute: {code: 8, text: 'Order Disputed'}, - Resolve: {code: 9, text: 'Order Dispute Resolved'}, - PayRequest: {code: 10, text: 'Payment Requested'}, - Authorize: {code: 11, text: 'Payment Approved'}, - Paid: {code: 14, text: 'Payment Processed'}, - Refund: {code: 12, text: 'Order Refund Requested'}, - Refunded: {code: 13, text: 'Order Refunded'} +let connectionProfileName = 'z2b-test-profile'; +let networkFile = 'zerotoblockchain-network.bna'; +let businessNetwork = 'zerotoblockchain-network'; + +let buyers, sellers, providers, shippers; +let s_string, p_string, sh_string; + +let orderStatus = { + Created: {code: 1, text: 'Order Created'}, + Bought: {code: 2, text: 'Order Purchased'}, + Cancelled: {code: 3, text: 'Order Cancelled'}, + Ordered: {code: 4, text: 'Order Submitted to Provider'}, + ShipRequest: {code: 5, text: 'Shipping Requested'}, + Delivered: {code: 6, text: 'Order Delivered'}, + Delivering: {code: 15, text: 'Order being Delivered'}, + Backordered: {code: 7, text: 'Order Backordered'}, + Dispute: {code: 8, text: 'Order Disputed'}, + Resolve: {code: 9, text: 'Order Dispute Resolved'}, + PayRequest: {code: 10, text: 'Payment Requested'}, + Authorize: {code: 11, text: 'Payment Approved'}, + Paid: {code: 14, text: 'Payment Processed'}, + Refund: {code: 12, text: 'Order Refund Requested'}, + Refunded: {code: 13, text: 'Order Refunded'} }; /** * standard home page initialization routine * Refer to this by {@link initPage()}. */ - function initPage () +function initPage () { - // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English - goMultiLingual("US_English", "index"); - // memberLoad loads the members already present in the network - memberLoad(); - // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring - getChainEvents(); + // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English + goMultiLingual('US_English', 'index'); + // singleUX loads the members already present in the network + memberLoad(); + // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring + getChainEvents(); } diff --git a/Chapter07/HTML/js/z2b-seller.js b/Chapter07/HTML/js/z2b-seller.js index e10ede0..b45288d 100644 --- a/Chapter07/HTML/js/z2b-seller.js +++ b/Chapter07/HTML/js/z2b-seller.js @@ -13,150 +13,165 @@ */ // z2c-seller.js -var sellerOrderDiv = "sellerOrderDiv"; + +'use strict'; +let sellerOrderDiv = 'sellerOrderDiv'; /** - * load the seller User Experience + * load the administration Seller Experience */ function loadSellerUX () { - toLoad = "seller.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupSeller(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'seller.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupSeller(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupSeller(page[0], port[0]);}); + } } +/** + * load the administration User Experience + * @param {String} page - page to load + * @param {Integer} port - web socket port to use + */ function setupSeller(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("seller"); - msgPort = port.port; - wsDisplay('seller_messages', msgPort); - - // - // this section changes from the previous chapter, buyer changing to seller - // - + $('#body').empty(); + $('#body').append(page); + updatePage('seller'); + msgPort = port.port; + wsDisplay('seller_messages', msgPort); + let _clear = $('#seller_clear'); + let _list = $('#sellerOrderStatus'); + let _orderDiv = $('#'+sellerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + // + // this section changes from the previous chapter, buyer changing to seller + // + _list.on('click', function(){listSellerOrders();}); + $('#seller').empty(); + $('#seller').append(s_string); + $('#sellerCompany').empty(); + $('#sellerCompany').append(sellers[0].companyName); + $('#seller').on('change', function() { + $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty(); + $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName); + }); } /** * lists all orders for the selected seller */ function listSellerOrders() { - var options = {}; - // - // seller instead of buyer - // - options.id = $("#seller").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + // + // seller instead of buyer + // + options.id= $('#seller').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} - else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)} - }); - }); + { + if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} + else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);} + }); } /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatSellerOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Bought.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.ShipRequest.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivering.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Ordered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Backordered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Dispute.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Resolve.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Cancelled.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Paid.code: - - break; + // ========> Your Code Goes Here <========= + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - - _target.append(_str); - for (let each in _orders) + + _target.append(_str); + for (let each in _orders) {(function(_idx, _arr) - { $("#s_btn_"+_idx).on('click', function () + { $('#s_btn_'+_idx).on('click', function () { - var options = {}; - options.action = $("#s_action"+_idx).find(":selected").text(); - options.orderNo = $("#s_order"+_idx).text(); - options.participant = $("#seller").val(); - options.provider = $("#providers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#s_reason"+_idx).val();} - $("#seller_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + let options = {}; + options.action = $('#s_action'+_idx).find(':selected').text(); + options.orderNo = $('#s_order'+_idx).text(); + options.participant = $('#seller').val(); + options.provider = $('#providers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#s_reason'+_idx).val();} + $('#seller_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#seller_messages").prepend(formatMessage(_results.result)); }); + { $('#seller_messages').prepend(formatMessage(_results.result)); }); }); - })(each, _orders) - } + })(each, _orders); + } } \ No newline at end of file diff --git a/Chapter07/HTML/removeMember.html b/Chapter07/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter07/HTML/removeMember.html +++ b/Chapter07/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter07/buildAndDeploy b/Chapter07/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter07/buildAndDeploy +++ b/Chapter07/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter07/controller/env.json b/Chapter07/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter07/controller/env.json +++ b/Chapter07/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter07/controller/restapi/features/composer/autoLoad.js b/Chapter07/controller/restapi/features/composer/autoLoad.js index 1f5214f..ce3d81b 100644 --- a/Chapter07/controller/restapi/features/composer/autoLoad.js +++ b/Chapter07/controller/restapi/features/composer/autoLoad.js @@ -14,62 +14,57 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter07/controller/restapi/features/composer/hlcAdmin.js b/Chapter07/controller/restapi/features/composer/hlcAdmin.js index 27b12a3..8e9e8b9 100644 --- a/Chapter07/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter07/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter07/controller/restapi/features/composer/hlcClient.js b/Chapter07/controller/restapi/features/composer/hlcClient.js index 4dc805e..3e15cf2 100644 --- a/Chapter07/controller/restapi/features/composer/hlcClient.js +++ b/Chapter07/controller/restapi/features/composer/hlcClient.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,112 +115,109 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - - break; - case 'Request Payment': - console.log('Request Payment entered'); - - break; - case 'Refund': - console.log('Refund Payment entered'); - - break; - case 'Resolve': - console.log('Resolve entered'); - - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + // ========> Your Code Goes Here <========= + break; + case 'Request Payment': + // ========> Your Code Goes Here <========= + break; + case 'Refund': + // ========> Your Code Goes Here <========= + break; + case 'Resolve': + // ========> Your Code Goes Here <========= + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -225,85 +226,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter07/controller/restapi/features/text/ch/prompts.json b/Chapter07/controller/restapi/features/text/ch/prompts.json index d01c9b3..811c1a1 100644 --- a/Chapter07/controller/restapi/features/text/ch/prompts.json +++ b/Chapter07/controller/restapi/features/text/ch/prompts.json @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", diff --git a/Chapter07/controller/restapi/features/text/en-UK/prompts.json b/Chapter07/controller/restapi/features/text/en-UK/prompts.json index 7d166b6..a2490e6 100644 --- a/Chapter07/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter07/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "UK English", - "title": "Z2B Chapter 7", - "header": "Chapter 7: Building the Seller User Experience", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 7", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 7. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 7: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 7, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 7, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 7, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 7", + "header":"Chapter 7: Building the Seller User Experience", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter07/controller/restapi/features/text/en-US/prompts 2.json b/Chapter07/controller/restapi/features/text/en-US/prompts 2.json new file mode 100644 index 0000000..5884230 --- /dev/null +++ b/Chapter07/controller/restapi/features/text/en-US/prompts 2.json @@ -0,0 +1,219 @@ +{ + "index": {"language": "US English", + "title": "Z2B Chapter 7", + "header": "Chapter 7: Building the Seller User Experience", + "titleBar": "Zero to Blockchain Tutorial", + "idx_unified": "load Unified User Experience", + "idx_buyer": "load Buyer User Experience", + "idx_seller": "load Seller User Experience", + "idx_provider": "load Provider User Experience", + "idx_shipper": "load Shipper User Experience", + "idx_financeco": "load Finance Company User Experience", + "idx_roles": "Roles", + "idx_admin": "Admin", + "idx_adminUX": "load Admin User Experience", + "idx_preload": "Preload Network" + }, + "admin": { + "title": "Zero To Blockchain Chapter 7", + "npm": "Network Profile Management", + "npm_API": "API", + "npm_param": "Parameters", + "npm_dp_api": "delete profile", + "npm_dp_param": "profile name", + "npm_cp_api": "create Profile", + "npm_cp_param": "profile object", + "npm_ga_api": "get all connection profiles", + "npm_ga_param": "(none)", + "npm_g1_api": "get a specific network connection profile", + "npm_g1_param": "profile name", + "bnm": "Business Network Management", + "bnm_param": "Parameters", + "bnm_api": "API", + "bnm_nd_api": "deploy a network", + "bnm_nd_param": "network archive file, options", + "bnm_ni_api": "install new a network", + "bnm_ni_param": "network archive file, options", + "bnm_ns_api": "start an installed network", + "bnm_ns_param": "network name, options", + "bnm_nl_api": "list the deployed business networks", + "bnm_nl_param": "(none)", + "bnm_np_api": "touch a network, check compatibility", + "bnm_np_param": "business network name", + "bnm_nu_api": "take a business network off line", + "bnm_nu_param": "business network name<", + "bnm_nuu_api": "update an existing business network", + "bnm_nuu_param": "business network name, archive file", + "rm": "Resource Management", + "rm_api": "API", + "rm_param": "Parameters", + "rm_lr_api": "list members of a registry", + "rm_la_api": "List Assets in the registry", + "rm_la_param": "(none)", + "rm_am_api": "Add Member", + "rm_am_param": "Co Name, id, Type", + "rm_rm_api": "Remove Member", + "rm_gs_api": "getMemberSecret", + "bc": "BlockChain", + "bc_api": "API", + "bc_param": "Parameters", + "bc_gi_api": "initiate connection to blockchain", + "bc_gi_param": "(none)", + "bc_ge_api": "register for blockchain events", + "bc_ge_param": "(none)", + "bc_gh_api": "get Historian", + "bc_gh_param": "(none)" + }, + "buyer": { + "title": "Buyer Chapter 7. Select Buyer to see their view: ", + "newOrder": "Create New Order", + "orderStatus": "Display Order Status" + }, + "createConnectionProfile": { + "title": "type the name of the new profile here: ", + "cp_type": "type", + "cp_orderers": "orderers", + "cp_orderers_url": "url", + "cp_ca": "ca", + "cp_ca_url": "url", + "cp_ca_name": "name", + "cp_peers": "peers", + "cp_peers_event_url": "eventURL", + "cp_peers_request_url": "requestURL", + "cp_keyValStore": "keyValStore", + "cp_channel": "channel", + "cp_mspID": "mspID", + "cp_timeout": "timeout", + "cancel": "Cancel", + "submit": "Submit" + }, + "createMember": { + "cd_type": "Type", + "cd_buyer": "Buyer", + "cd_seller": "Seller", + "cd_shipper": "Shipper", + "cd_provider": "Provider", + "cd_financeco": "FinanceCo", + "cd_cn": "Company Name", + "cd_e": "email Address", + "cancelNewOrder": "Cancel", + "submitNewOrder": "Submit" + }, + "createOrder": { + "title": "Create New Order", + "selectVendor": "Select Vendor: ", + "cn_on": "Order Number", + "cn_status": "Status", + "cn_date": "Date", + "cn_total": "Total", + "cn_selectItem": "Select Item", + "addItem": "Add Item", + "cancelNewOrder": "Cancel", + "submitNewOrder": "Submit" + }, + "deleteConnectionProfile": { + "title": "Select Profile to delete: ", + "cancel": "Cancel", + "submit": "Submit" + }, + "financeCo": { + "title": "Zero To Blockchain Chapter 7: The Global Financier", + "financeCOclear": "Clear Window", + "financeCOorderStatus": "Display Order Status" + }, + "getMemberSecret": { + "gs_type": "Type", + "gs_members": "Members", + "gs_company": "Company Name", + "gs_email": "email Address", + "gs_userID": "userID", + "gs_secret": "secret", + "cancel": "Cancel", + "submit": "Submit" + }, + "provider": { + "title": "Provider Chapter 7, Select Provider to see their view: ", + "provider_clear": "Clear Window", + "providerOrderStatus": "Display Order Status" + }, + "removeMember": { + "rm_type": "Type", + "rm_members": "Members", + "rm_company": "Company Name", + "rm_email": "email Address", + "rm_userID": "userID", + "rm_secret": "secret", + "cancel": "Cancel", + "submit": "Submit" + }, + "seller": { + "title": "Seller Chapter 7, Select Seller to see their view: ", + "seller_clear": "Clear Window", + "sellerOrderStatus": "Display Order Status" + }, + "shipper": { + "title": "Shipper Chapter 7, Select Shipper to see their view: ", + "shipper_clear": "Clear Window", + "shipperOrderStatus": "Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, + "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, + "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, + "Purchase": {"select": "Purchase", "message": "Purchase"}, + "Cancel": {"select": "Cancel", "message": "Cancel"}, + "Pay": {"select": "Pay", "message": "Pay"}, + "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, + "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, + "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, + "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, + "Delivered": {"select": "Delivered", "message": "Delivered"}, + "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, + "Order": {"select": "Order", "message": "Order From Supplier"}, + "NoAction": {"select": "NoAction", "message": "Take No Action"}, + "ex_button": "Execute", + "ca_button": "Cancel", + "orderno": "Order #", + "status": "Status", + "total": "Total", + "seller": "Seller: ", + "itemno": "Item Number", + "description": "Description", + "qty": "Quantity", + "price": "Price", + "processing_msg": "Processing {0} request for order number: {1}", + "b_no_order_msg": "No orders for this buyer: ", + "s_no_order_msg": "No orders for this seller: ", + "p_no_order_msg": "No orders for this provider: ", + "sh_no_order_msg": "No orders for this shipper: ", + "create_msg": "Processing Create Order request", + "buyer": "Buyer: " + }, + "financeCoOrder": { + "status": "Current Status: ", + "action": "Action", + "by": "By", + "date": "Date", + "comments": "Comments", + "created": "Created", + "cancelled": "Cancelled?", + "notCancel": "(not Cancelled)", + "purchased": "Purchased", + "noPurchase": "(no Purchase Request)", + "thirdParty": "3rd Party Order", + "nothirdParty": "(not yet sent to 3rd Party)", + "backordered": "Backordered?", + "notBackordered": "(not Backordered)", + "shippingRequested": "Shipping Requested", + "noRequestShip": "(No Request to Shipper)", + "shippingStarted": "Shipping Started", + "noDeliveryStart": "(Delivery not Started)", + "delivered": "Delivered", + "notDelivered": "(not yet Delivered)", + "payRequested": "Payment Requested", + "noRequest": "(no request for payment)", + "disputed": "Dispute Raised", + "noDispute": "(not in Dispute)" + } +} diff --git a/Chapter07/controller/restapi/features/text/en-US/prompts.json b/Chapter07/controller/restapi/features/text/en-US/prompts.json index 5884230..a36a701 100644 --- a/Chapter07/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter07/controller/restapi/features/text/en-US/prompts.json @@ -53,7 +53,10 @@ "rm_am_api": "Add Member", "rm_am_param": "Co Name, id, Type", "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", "bc": "BlockChain", "bc_api": "API", "bc_param": "Parameters", @@ -96,8 +99,8 @@ "cd_financeco": "FinanceCo", "cd_cn": "Company Name", "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" + "cancel": "Cancel", + "submit": "Submit" }, "createOrder": { "title": "Create New Order", diff --git a/Chapter07/controller/restapi/features/text/es-LA/prompts.json b/Chapter07/controller/restapi/features/text/es-LA/prompts.json index 45c63d2..01eb382 100644 --- a/Chapter07/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter07/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 7", - "header":"Capítulo 7: Construyendo la experiencia del usuario del vendedor", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 7", + "header":"Capítulo 7: Construyendo la experiencia del usuario del vendedor", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter07/controller/restapi/features/text/fr/prompts.json b/Chapter07/controller/restapi/features/text/fr/prompts.json index 27d7798..db9b6f7 100644 --- a/Chapter07/controller/restapi/features/text/fr/prompts.json +++ b/Chapter07/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 7", - "header":"Chapitre 7 : Construire l'experience du vendeur", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 05", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { - "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", - "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { - "title":"Zero to Blockchain Chapitre 10: Le financier mondial", - "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { - "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", - "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { - "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", - "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { - "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", - "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer(0) demander le numero de commande:(1)", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 7", + "header":"Chapitre 7 : Construire l'experience du vendeur", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { + "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", + "newOrder":"Créér une nouvelle commande", + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { + "title":"Zero to Blockchain Chapitre 10: Le financier mondial", + "financeCOclear":"Effacer le contenu de la fenetre", + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { + "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", + "provider_clear":"Effacer le contenu de la fenetre", + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { + "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", + "seller_clear":"Effacer le contenu de la fenetre", + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { + "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", + "shipper_clear":"Effacer le contenu de la fenetre", + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter07/controller/restapi/features/text/jp/prompts.json b/Chapter07/controller/restapi/features/text/jp/prompts.json index e4d7d6b..05cb2dd 100644 --- a/Chapter07/controller/restapi/features/text/jp/prompts.json +++ b/Chapter07/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 7章", - "header":"弟 7章: 販売者ユーザー経験の構築", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟05章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟07章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 7章", + "header":"弟 7章: 販売者ユーザー経験の構築", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter07/controller/restapi/features/text/languages.json b/Chapter07/controller/restapi/features/text/languages.json index 91b0348..8ee6b21 100644 --- a/Chapter07/controller/restapi/features/text/languages.json +++ b/Chapter07/controller/restapi/features/text/languages.json @@ -6,6 +6,6 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, - "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} + "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } \ No newline at end of file diff --git a/Chapter07/controller/restapi/features/text/pt/prompts.json b/Chapter07/controller/restapi/features/text/pt/prompts.json index 4a3c1db..9521b1e 100644 --- a/Chapter07/controller/restapi/features/text/pt/prompts.json +++ b/Chapter07/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 7", + "header":"Capítulo 7: Construindo a Experiência de Usuário Vendedor", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter07/controller/restapi/router.js b/Chapter07/controller/restapi/router.js index 28ac0af..6fa15bd 100644 --- a/Chapter07/controller/restapi/router.js +++ b/Chapter07/controller/restapi/router.js @@ -12,19 +12,19 @@ * limitations under the License. */ +'use strict'; -var express = require('express'); -var router = express.Router(); -var format = require('date-format'); +let express = require('express'); +let router = express.Router(); +let format = require('date-format'); -var multi_lingual = require('./features/multi_lingual'); -var resources = require('./features/resources'); -var getCreds = require('./features/getCredentials'); -var hlcAdmin = require('./features/composer/hlcAdmin'); -var hlcClient = require('./features/composer/hlcClient'); -var setup = require('./features/composer/autoLoad'); - -var hlcFabric = require('./features/composer/queryBlockChain'); +let multi_lingual = require('./features/multi_lingual'); +let resources = require('./features/resources'); +let getCreds = require('./features/getCredentials'); +let hlcAdmin = require('./features/composer/hlcAdmin'); +let hlcClient = require('./features/composer/hlcClient'); +let setup = require('./features/composer/autoLoad'); +let hlcFabric = require('./features/composer/queryBlockChain'); router.post('/setup/autoLoad*', setup.autoLoad); router.get('/setup/getPort*', setup.getPort); @@ -33,13 +33,29 @@ router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); router.get('/fabric/getHistory', hlcAdmin.getHistory); module.exports = router; -var count = 0; +let count = 0; +/** + * This is a request tracking function which logs to the terminal window each request coming in to the web serve and + * increments a counter to allow the requests to be sequenced. + * @param {express.req} req - the inbound request object from the client + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * + * @function + */ router.use(function(req, res, next) { - count++; - console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); - next(); // make sure we go to the next routes and don't stop here + count++; + console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); + next(); // make sure we go to the next routes and don't stop here }); +// the following get and post statements tell nodeJS what to do when a request comes in +// The request is the single quoted phrase following the get( or post( statement. +// the text at the end identifies which function in which require(d) module to implement +// These are searched in order by get/post request. +// The asterisk (*) means 'ignore anything following this point' +// which means we have to be careful about ordering these statements. +// router.get('/api/getSupportedLanguages*',multi_lingual.languages); router.get('/api/getTextLocations*',multi_lingual.locations); router.post('/api/selectedPrompts*',multi_lingual.prompts); @@ -54,7 +70,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -71,7 +86,11 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); +// router requests specific to the Buyer router.get('/composer/client/getItemTable*', hlcClient.getItemTable); router.post('/composer/client/getMyOrders*', hlcClient.getMyOrders); router.post('/composer/client/addOrder*', hlcClient.addOrder); diff --git a/Chapter07/createArchive.sh b/Chapter07/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter07/createArchive.sh +++ b/Chapter07/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter07/deployNetwork.sh b/Chapter07/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter07/deployNetwork.sh +++ b/Chapter07/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter07/favicon.ico b/Chapter07/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter07/favicon.ico and b/Chapter07/favicon.ico differ diff --git a/Chapter07/network/dist/networkadmin.card b/Chapter07/network/dist/networkadmin.card new file mode 100644 index 0000000..e8c8187 Binary files /dev/null and b/Chapter07/network/dist/networkadmin.card differ diff --git a/Chapter07/network/package.json b/Chapter07/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter07/network/package.json +++ b/Chapter07/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter07/network/test/sample.js b/Chapter07/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter07/network/test/sample.js +++ b/Chapter07/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter07/package.json b/Chapter07/package.json index 1d086ff..57535e3 100644 --- a/Chapter07/package.json +++ b/Chapter07/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter07/startup.sh b/Chapter07/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter07/startup.sh +++ b/Chapter07/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter07/z2c_login b/Chapter07/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter07/z2c_login +++ b/Chapter07/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter08/Documentation/Chinese/Z2B_Chapter08.pdf b/Chapter08/Documentation/Chinese/Z2B_Chapter08.pdf index f8eb6cb..c67cb28 100644 Binary files a/Chapter08/Documentation/Chinese/Z2B_Chapter08.pdf and b/Chapter08/Documentation/Chinese/Z2B_Chapter08.pdf differ diff --git a/Chapter08/Documentation/Chinese/Z2B_Chapter08.pptx b/Chapter08/Documentation/Chinese/Z2B_Chapter08.pptx new file mode 100644 index 0000000..8314a3d Binary files /dev/null and b/Chapter08/Documentation/Chinese/Z2B_Chapter08.pptx differ diff --git a/Chapter08/Documentation/Espanol/Z2B_Chapter08.pdf b/Chapter08/Documentation/Espanol/Z2B_Chapter08.pdf index cbf7917..4f1857c 100644 Binary files a/Chapter08/Documentation/Espanol/Z2B_Chapter08.pdf and b/Chapter08/Documentation/Espanol/Z2B_Chapter08.pdf differ diff --git a/Chapter08/Documentation/Espanol/Z2B_Chapter08.pptx b/Chapter08/Documentation/Espanol/Z2B_Chapter08.pptx new file mode 100644 index 0000000..f039438 Binary files /dev/null and b/Chapter08/Documentation/Espanol/Z2B_Chapter08.pptx differ diff --git a/Chapter08/Documentation/Japanese/Z2B_Chapter08.pdf b/Chapter08/Documentation/Japanese/Z2B_Chapter08.pdf index caf3154..e6559c7 100644 Binary files a/Chapter08/Documentation/Japanese/Z2B_Chapter08.pdf and b/Chapter08/Documentation/Japanese/Z2B_Chapter08.pdf differ diff --git a/Chapter08/Documentation/Japanese/Z2B_Chapter08.pptx b/Chapter08/Documentation/Japanese/Z2B_Chapter08.pptx new file mode 100644 index 0000000..42680fa Binary files /dev/null and b/Chapter08/Documentation/Japanese/Z2B_Chapter08.pptx differ diff --git a/Chapter08/Documentation/Z2B Chapter08.pdf b/Chapter08/Documentation/Z2B Chapter08.pdf index ad2c432..0617312 100644 Binary files a/Chapter08/Documentation/Z2B Chapter08.pdf and b/Chapter08/Documentation/Z2B Chapter08.pdf differ diff --git a/Chapter08/Documentation/answers/composer/hlcClient_complete.js b/Chapter08/Documentation/answers/composer/hlcClient_complete.js index ea8464c..f43ff92 100644 --- a/Chapter08/Documentation/answers/composer/hlcClient_complete.js +++ b/Chapter08/Documentation/answers/composer/hlcClient_complete.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,150 +115,148 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': - break; - case 'Delivered': - console.log('Delivered entered'); - - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); + break; + case 'Delivered': + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -263,85 +265,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter08/Documentation/answers/js/z2b-provider_complete.js b/Chapter08/Documentation/answers/js/z2b-provider_complete.js index e002d77..99d667f 100644 --- a/Chapter08/Documentation/answers/js/z2b-provider_complete.js +++ b/Chapter08/Documentation/answers/js/z2b-provider_complete.js @@ -14,67 +14,71 @@ // z2c-provider.js -var providerOrderDiv = "providerOrderDiv"; +'use strict'; + +let providerOrderDiv = 'providerOrderDiv'; /** * load the Provider User Experience */ function loadProviderUX () { - toLoad = "provider.html"; + let toLoad = 'provider.html'; getPort(); - if (buyers.length === 0) + if (buyers.length === 0) { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupProvider(page[0], port[0]);}); } else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupProvider(page[0], port[0]);}); + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupProvider(page[0], port[0]);}); } - } - +} + +/** + * load the Provider User Experience + * @param {String} page - the name of the page to load + * @param {Integer} port - the port number to use + */ function setupProvider(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("provider"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('provider_messages', msgPort); - var _clear = $("#provider_clear"); - var _list = $("#providerOrderStatus"); - var _orderDiv = $("#"+providerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listProviderOrders()}); - $("#provider").empty(); - $("#provider").append(p_string); - $("#providerCompany").empty(); - $("#providerCompany").append(providers[0].companyName); - $("#provider").on('change', function() { - $("#providerCompany").empty(); _orderDiv.empty(); $("#provider_messages").empty(); - $("#providerCompany").append(findMember($("#provider").find(":selected").val(),providers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('provider'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('provider_messages', msgPort); + let _clear = $('#provider_clear'); + let _list = $('#providerOrderStatus'); + let _orderDiv = $('#'+providerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listProviderOrders();}); + $('#provider').empty(); + $('#provider').append(p_string); + $('#providerCompany').empty(); + $('#providerCompany').append(providers[0].companyName); + $('#provider').on('change', function() { + $('#providerCompany').empty(); _orderDiv.empty(); $('#provider_messages').empty(); + $('#providerCompany').append(findMember($('#provider').find(':selected').val(),providers).companyName); + }); } /** * lists all orders for the selected Provider */ function listProviderOrders() { - var options = {}; - options.id = $("#provider").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#provider').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#providerOrderDiv").empty(); $("#providerOrderDiv").append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} - else{formatProviderOrders($("#providerOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#providerOrderDiv').empty(); $('#providerOrderDiv').append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} + else{formatProviderOrders($('#providerOrderDiv'), _results.orders);} + }); } + /** * used by the listOrders() function * formats the orders for a Provider. Orders to be formatted are provided in the _orders array @@ -84,97 +88,97 @@ function listProviderOrders() */ function formatProviderOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let b_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + b_string = ''; + // + // each order can have different states and the action that a Provider can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += ''; - _action += ''; - b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; - break; + _date = _arr[_idx].ordered; + _action += ''; + _action += ''; + b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += ''; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= ''; + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#p_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#p_action'+_idx).find(':selected').text(); + options.orderNo = $('#p_order'+_idx).text(); + options.participant = $('#provider').val(); + options.shipper = $('#shippers'+_idx).find(':selected').val(); + if ((options.action == 'Resolve') || (options.action === 'Refund') || (options.action === 'BackOrder')) {options.reason = $('#p_reason'+_idx).val();} + console.log(options); + $('#provider_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#provider_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#p_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#p_action"+_idx).find(":selected").text(); - options.orderNo = $("#p_order"+_idx).text(); - options.participant = $("#provider").val(); - options.shipper = $("#shippers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund') || (options.action == 'BackOrder')) {options.reason = $("#p_reason"+_idx).val();} - console.log(options); - $("#provider_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#provider_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter08/HTML/CSS/pageStyles.css b/Chapter08/HTML/CSS/pageStyles.css index d6d67bf..6038b35 100755 --- a/Chapter08/HTML/CSS/pageStyles.css +++ b/Chapter08/HTML/CSS/pageStyles.css @@ -47,6 +47,17 @@ body {height: 100%} overflow: auto; } } +.strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: #5DC15D;} .provider { background-color: #8A99D3;} @@ -72,14 +83,14 @@ p.message{ } .scrollingPaneLeft{ position: fixed; - height: 85%; + height: 80%; margin-left: 1%; width: 45%; overflow: auto; } .scrollingPaneRight{ position: fixed; - height: 85%; + height: 80%; margin-left: 50%; width: 45%; overflow: auto; @@ -87,10 +98,10 @@ p.message{ .blockchain { background-color: black; position: fixed; - height: 9%; + height: 8%; margin-left: 1%; width: 95%; - top: 90%; + top: 92%; padding: 4px; overflow-x: auto; overflow-y: hidden; diff --git a/Chapter08/HTML/admin.html b/Chapter08/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter08/HTML/admin.html +++ b/Chapter08/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
-
+ \ No newline at end of file diff --git a/Chapter08/HTML/adminHelp.html b/Chapter08/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter08/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter08/HTML/favicon.ico b/Chapter08/HTML/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter08/HTML/favicon.ico and b/Chapter08/HTML/favicon.ico differ diff --git a/Chapter08/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter08/HTML/fonts/glyphicons-halflings-regular.ttf index 1413fc6..1f85312 100644 Binary files a/Chapter08/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter08/HTML/fonts/glyphicons-halflings-regular.ttf differ diff --git a/Chapter08/HTML/icons/Search.ico b/Chapter08/HTML/icons/Search.ico index e1d39ae..fd437a0 100755 Binary files a/Chapter08/HTML/icons/Search.ico and b/Chapter08/HTML/icons/Search.ico differ diff --git a/Chapter08/HTML/js/z2b-admin.js b/Chapter08/HTML/js/z2b-admin.js index c716cb8..67f421a 100644 --- a/Chapter08/HTML/js/z2b-admin.js +++ b/Chapter08/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -130,55 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter08/HTML/js/z2b-buyer.js b/Chapter08/HTML/js/z2b-buyer.js index 37f4b2c..535f938 100644 --- a/Chapter08/HTML/js/z2b-buyer.js +++ b/Chapter08/HTML/js/z2b-buyer.js @@ -14,166 +14,173 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; +'use strict'; + +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#body").empty(); - $("#body").append(page); - // update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#body').empty(); + $('#body').append(page); + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() { _orderDiv.empty(); $("#buyer_messages").empty(); $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; }); + $('#company')[0].innerText = buyers[0].companyName; + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array @@ -183,113 +190,114 @@ function listOrders() */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + })(each, _orders) + } } \ No newline at end of file diff --git a/Chapter08/HTML/js/z2b-initiate.js b/Chapter08/HTML/js/z2b-initiate.js index b566a28..290ef03 100644 --- a/Chapter08/HTML/js/z2b-initiate.js +++ b/Chapter08/HTML/js/z2b-initiate.js @@ -46,7 +46,7 @@ var orderStatus = { { // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English goMultiLingual("US_English", "index"); - // memberLoad loads the members already present in the network + // singleUX loads the members already present in the network memberLoad(); // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring getChainEvents(); diff --git a/Chapter08/HTML/js/z2b-provider.js b/Chapter08/HTML/js/z2b-provider.js index 3443893..80a95f6 100644 --- a/Chapter08/HTML/js/z2b-provider.js +++ b/Chapter08/HTML/js/z2b-provider.js @@ -14,66 +14,71 @@ // z2c-provider.js -var providerOrderDiv = "providerOrderDiv"; +'use strict'; + +let providerOrderDiv = 'providerOrderDiv'; /** * load the Provider User Experience */ function loadProviderUX () { - toLoad = "provider.html"; + let toLoad = 'provider.html'; getPort(); - if (buyers.length === 0) + if (buyers.length === 0) { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupProvider(page[0], port[0]);}); } else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupProvider(page[0], port[0]);}); + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupProvider(page[0], port[0]);}); } - } - +} + +/** + * load the Provider User Experience + * @param {String} page - the name of the page to load + * @param {Integer} port - the port number to use + */ function setupProvider(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("provider"); - msgPort = port.port; - wsDisplay('provider_messages', msgPort); - var _clear = $("#provider_clear"); - var _list = $("#providerOrderStatus"); - var _orderDiv = $("#"+providerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listProviderOrders()}); - $("#provider").empty(); - $("#provider").append(p_string); - $("#providerCompany").empty(); - $("#providerCompany").append("something"); - $("#provider").on('change', function() { - $("#providerCompany").empty(); _orderDiv.empty(); $("#provider_messages").empty(); - $("#providerCompany").append(findMember($("#provider").find(":selected").val(),providers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('provider'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('provider_messages', msgPort); + let _clear = $('#provider_clear'); + let _list = $('#providerOrderStatus'); + let _orderDiv = $('#'+providerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listProviderOrders();}); + $('#provider').empty(); + $('#provider').append(p_string); + $('#providerCompany').empty(); + $('#providerCompany').append(providers[0].companyName); + $('#provider').on('change', function() { + $('#providerCompany').empty(); _orderDiv.empty(); $('#provider_messages').empty(); + $('#providerCompany').append(findMember($('#provider').find(':selected').val(),providers).companyName); + }); } /** * lists all orders for the selected Provider */ function listProviderOrders() { - var options = {}; - options.id = $("#provider").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#provider').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#providerOrderDiv").empty(); $("#providerOrderDiv").append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} - else{formatProviderOrders($("#providerOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#providerOrderDiv').empty(); $('#providerOrderDiv').append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} + else{formatProviderOrders($('#providerOrderDiv'), _results.orders);} + }); } + /** * used by the listOrders() function * formats the orders for a Provider. Orders to be formatted are provided in the _orders array @@ -83,89 +88,89 @@ function listProviderOrders() */ function formatProviderOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let b_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + b_string = ''; + // + // each order can have different states and the action that a Provider can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.Ordered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Cancelled.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.ShipRequest.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Backordered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivering.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Resolve.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Dispute.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Cancelled.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Paid.code: - - break; + // ========> Your Code Goes Here <========= + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= ''; + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#p_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#p_action'+_idx).find(':selected').text(); + options.orderNo = $('#p_order'+_idx).text(); + options.participant = $('#provider').val(); + options.shipper = $('#shippers'+_idx).find(':selected').val(); + if ((options.action == 'Resolve') || (options.action === 'Refund') || (options.action === 'BackOrder')) {options.reason = $('#p_reason'+_idx).val();} + console.log(options); + $('#provider_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#provider_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#p_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#p_action"+_idx).find(":selected").text(); - options.orderNo = $("#p_order"+_idx).text(); - options.participant = $("#provider").val(); - options.shipper = $("#shippers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund') || (options.action == 'BackOrder')) {options.reason = $("#p_reason"+_idx).val();} - console.log(options); - $("#provider_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#provider_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter08/HTML/js/z2b-seller.js b/Chapter08/HTML/js/z2b-seller.js index 7099a9b..ecc7209 100644 --- a/Chapter08/HTML/js/z2b-seller.js +++ b/Chapter08/HTML/js/z2b-seller.js @@ -13,167 +13,171 @@ */ // z2c-seller.js -var sellerOrderDiv = "sellerOrderDiv"; + +'use strict'; +let sellerOrderDiv = 'sellerOrderDiv'; /** - * load the administration User Experience + * load the administration Seller Experience */ function loadSellerUX () { - toLoad = "seller.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupSeller(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'seller.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupSeller(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupSeller(page[0], port[0]);}); + } } +/** + * load the administration User Experience + * @param {String} page - page to load + * @param {Integer} port - web socket port to use + */ function setupSeller(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("seller"); - msgPort = port.port; - wsDisplay('seller_messages', msgPort); - var _clear = $("#seller_clear"); - var _list = $("#sellerOrderStatus"); - var _orderDiv = $("#"+sellerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - // - // this section changes from the previous chapter, buyer changing to seller - // - _list.on('click', function(){listSellerOrders()}); - $("#seller").empty(); - $("#seller").append(s_string); - $("#sellerCompany").empty(); - $("#sellerCompany").append(sellers[0].companyName); - $("#seller").on('change', function() { - $("#sellerCompany").empty(); _orderDiv.empty(); $("#seller_messages").empty(); - $("#sellerCompany").append(findMember($("#seller").find(":selected").val(),sellers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('seller'); + msgPort = port.port; + wsDisplay('seller_messages', msgPort); + let _clear = $('#seller_clear'); + let _list = $('#sellerOrderStatus'); + let _orderDiv = $('#'+sellerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + // + // this section changes from the previous chapter, buyer changing to seller + // + _list.on('click', function(){listSellerOrders();}); + $('#seller').empty(); + $('#seller').append(s_string); + $('#sellerCompany').empty(); + $('#sellerCompany').append(sellers[0].companyName); + $('#seller').on('change', function() { + $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty(); + $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName); + }); } /** * lists all orders for the selected seller */ function listSellerOrders() { - var options = {}; - // - // seller instead of buyer - // - options.id = $("#seller").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + // + // seller instead of buyer + // + options.id= $('#seller').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} - else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)} - }); - }); + { + if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} + else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);} + }); } /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatSellerOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += ''; - break; + _date = _arr[_idx].bought; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - var _string = '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + let _string = '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - - _target.append(_str); - for (let each in _orders) + + _target.append(_str); + for (let each in _orders) {(function(_idx, _arr) - { $("#s_btn_"+_idx).on('click', function () + { $('#s_btn_'+_idx).on('click', function () { - var options = {}; - options.action = $("#s_action"+_idx).find(":selected").text(); - options.orderNo = $("#s_order"+_idx).text(); - options.participant = $("#seller").val(); - options.provider = $("#providers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#s_reason"+_idx).val();} - $("#seller_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + let options = {}; + options.action = $('#s_action'+_idx).find(':selected').text(); + options.orderNo = $('#s_order'+_idx).text(); + options.participant = $('#seller').val(); + options.provider = $('#providers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#s_reason'+_idx).val();} + $('#seller_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#seller_messages").prepend(formatMessage(_results.result)); }); + { $('#seller_messages').prepend(formatMessage(_results.result)); }); }); - })(each, _orders) - } + })(each, _orders); + } } \ No newline at end of file diff --git a/Chapter08/HTML/removeMember.html b/Chapter08/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter08/HTML/removeMember.html +++ b/Chapter08/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter08/buildAndDeploy b/Chapter08/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter08/buildAndDeploy +++ b/Chapter08/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter08/controller/env.json b/Chapter08/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter08/controller/env.json +++ b/Chapter08/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter08/controller/restapi/features/composer/autoLoad.js b/Chapter08/controller/restapi/features/composer/autoLoad.js index 1f5214f..ce3d81b 100644 --- a/Chapter08/controller/restapi/features/composer/autoLoad.js +++ b/Chapter08/controller/restapi/features/composer/autoLoad.js @@ -14,62 +14,57 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter08/controller/restapi/features/composer/hlcAdmin.js b/Chapter08/controller/restapi/features/composer/hlcAdmin.js index 27b12a3..8e9e8b9 100644 --- a/Chapter08/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter08/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter08/controller/restapi/features/composer/hlcClient.js b/Chapter08/controller/restapi/features/composer/hlcClient.js index 6e74941..0c1a14a 100644 --- a/Chapter08/controller/restapi/features/composer/hlcClient.js +++ b/Chapter08/controller/restapi/features/composer/hlcClient.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,133 +115,132 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': - break; - case 'BackOrder': - console.log('BackOrder entered'); - - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); + break; + case 'BackOrder': + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -246,85 +249,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter08/controller/restapi/features/text/ch/prompts.json b/Chapter08/controller/restapi/features/text/ch/prompts.json index 745eeca..abd4589 100644 --- a/Chapter08/controller/restapi/features/text/ch/prompts.json +++ b/Chapter08/controller/restapi/features/text/ch/prompts.json @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", diff --git a/Chapter08/controller/restapi/features/text/en-UK/prompts.json b/Chapter08/controller/restapi/features/text/en-UK/prompts.json index a812bf9..9a52dd4 100644 --- a/Chapter08/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter08/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "UK English", - "title": "Z2B Chapter 8", - "header": "Chapter 8: Building the Provider User Experience", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 8", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 8. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 8: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 8, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 8, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 8, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 8", + "header":"Chapter 8: Building the Provider User Experience", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter08/controller/restapi/features/text/en-US/prompts.json b/Chapter08/controller/restapi/features/text/en-US/prompts.json index c28b0bb..fb7ab96 100644 --- a/Chapter08/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter08/controller/restapi/features/text/en-US/prompts.json @@ -53,7 +53,10 @@ "rm_am_api": "Add Member", "rm_am_param": "Co Name, id, Type", "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", "bc": "BlockChain", "bc_api": "API", "bc_param": "Parameters", @@ -96,8 +99,8 @@ "cd_financeco": "FinanceCo", "cd_cn": "Company Name", "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" + "cancel": "Cancel", + "submit": "Submit" }, "createOrder": { "title": "Create New Order", diff --git a/Chapter08/controller/restapi/features/text/es-LA/prompts.json b/Chapter08/controller/restapi/features/text/es-LA/prompts.json index c4179d7..8384fcf 100644 --- a/Chapter08/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter08/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 8", - "header":"Capítulo 8: Construyendo la experiencia del usuario del proveedor", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 8", + "header":"Capítulo 8: Construyendo la experiencia del usuario del proveedor", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter08/controller/restapi/features/text/fr/prompts.json b/Chapter08/controller/restapi/features/text/fr/prompts.json index db4da7a..7fd077c 100644 --- a/Chapter08/controller/restapi/features/text/fr/prompts.json +++ b/Chapter08/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 8", - "header":"Chapitre 8 : Construire l'experience du fournisseur", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 05", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { - "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", - "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { - "title":"Zero to Blockchain Chapitre 10: Le financier mondial", - "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { - "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", - "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { - "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", - "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { - "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", - "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer(0) demander le numero de commande:(1)", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 8", + "header":"Chapitre 8 : Construire l'experience du fournisseur", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { + "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", + "newOrder":"Créér une nouvelle commande", + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { + "title":"Zero to Blockchain Chapitre 10: Le financier mondial", + "financeCOclear":"Effacer le contenu de la fenetre", + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { + "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", + "provider_clear":"Effacer le contenu de la fenetre", + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { + "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", + "seller_clear":"Effacer le contenu de la fenetre", + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { + "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", + "shipper_clear":"Effacer le contenu de la fenetre", + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter08/controller/restapi/features/text/jp/prompts.json b/Chapter08/controller/restapi/features/text/jp/prompts.json index 4c1124f..d1bc23b 100644 --- a/Chapter08/controller/restapi/features/text/jp/prompts.json +++ b/Chapter08/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 8章", - "header":"弟 8章: プロバイダユーザー経験の構築", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟05章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟07章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 8章", + "header":"弟 8章: プロバイダユーザー経験の構築", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter08/controller/restapi/features/text/languages.json b/Chapter08/controller/restapi/features/text/languages.json index 91b0348..8ee6b21 100644 --- a/Chapter08/controller/restapi/features/text/languages.json +++ b/Chapter08/controller/restapi/features/text/languages.json @@ -6,6 +6,6 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, - "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} + "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } \ No newline at end of file diff --git a/Chapter08/controller/restapi/features/text/pt/prompts.json b/Chapter08/controller/restapi/features/text/pt/prompts.json index 4a3c1db..7a557e2 100644 --- a/Chapter08/controller/restapi/features/text/pt/prompts.json +++ b/Chapter08/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 8", + "header":"Capítulo 8: Construindo a Experiência de Usuário Fornecedor", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter08/controller/restapi/router.js b/Chapter08/controller/restapi/router.js index 28ac0af..6fa15bd 100644 --- a/Chapter08/controller/restapi/router.js +++ b/Chapter08/controller/restapi/router.js @@ -12,19 +12,19 @@ * limitations under the License. */ +'use strict'; -var express = require('express'); -var router = express.Router(); -var format = require('date-format'); +let express = require('express'); +let router = express.Router(); +let format = require('date-format'); -var multi_lingual = require('./features/multi_lingual'); -var resources = require('./features/resources'); -var getCreds = require('./features/getCredentials'); -var hlcAdmin = require('./features/composer/hlcAdmin'); -var hlcClient = require('./features/composer/hlcClient'); -var setup = require('./features/composer/autoLoad'); - -var hlcFabric = require('./features/composer/queryBlockChain'); +let multi_lingual = require('./features/multi_lingual'); +let resources = require('./features/resources'); +let getCreds = require('./features/getCredentials'); +let hlcAdmin = require('./features/composer/hlcAdmin'); +let hlcClient = require('./features/composer/hlcClient'); +let setup = require('./features/composer/autoLoad'); +let hlcFabric = require('./features/composer/queryBlockChain'); router.post('/setup/autoLoad*', setup.autoLoad); router.get('/setup/getPort*', setup.getPort); @@ -33,13 +33,29 @@ router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); router.get('/fabric/getHistory', hlcAdmin.getHistory); module.exports = router; -var count = 0; +let count = 0; +/** + * This is a request tracking function which logs to the terminal window each request coming in to the web serve and + * increments a counter to allow the requests to be sequenced. + * @param {express.req} req - the inbound request object from the client + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * + * @function + */ router.use(function(req, res, next) { - count++; - console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); - next(); // make sure we go to the next routes and don't stop here + count++; + console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); + next(); // make sure we go to the next routes and don't stop here }); +// the following get and post statements tell nodeJS what to do when a request comes in +// The request is the single quoted phrase following the get( or post( statement. +// the text at the end identifies which function in which require(d) module to implement +// These are searched in order by get/post request. +// The asterisk (*) means 'ignore anything following this point' +// which means we have to be careful about ordering these statements. +// router.get('/api/getSupportedLanguages*',multi_lingual.languages); router.get('/api/getTextLocations*',multi_lingual.locations); router.post('/api/selectedPrompts*',multi_lingual.prompts); @@ -54,7 +70,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -71,7 +86,11 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); +// router requests specific to the Buyer router.get('/composer/client/getItemTable*', hlcClient.getItemTable); router.post('/composer/client/getMyOrders*', hlcClient.getMyOrders); router.post('/composer/client/addOrder*', hlcClient.addOrder); diff --git a/Chapter08/createArchive.sh b/Chapter08/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter08/createArchive.sh +++ b/Chapter08/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter08/deployNetwork.sh b/Chapter08/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter08/deployNetwork.sh +++ b/Chapter08/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter08/favicon.ico b/Chapter08/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter08/favicon.ico and b/Chapter08/favicon.ico differ diff --git a/Chapter08/network/dist/networkadmin.card b/Chapter08/network/dist/networkadmin.card new file mode 100644 index 0000000..6e9c9fa Binary files /dev/null and b/Chapter08/network/dist/networkadmin.card differ diff --git a/Chapter08/network/package.json b/Chapter08/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter08/network/package.json +++ b/Chapter08/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter08/network/test/sample.js b/Chapter08/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter08/network/test/sample.js +++ b/Chapter08/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter08/package.json b/Chapter08/package.json index 1d086ff..57535e3 100644 --- a/Chapter08/package.json +++ b/Chapter08/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter08/startup.sh b/Chapter08/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter08/startup.sh +++ b/Chapter08/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter08/z2c_login b/Chapter08/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter08/z2c_login +++ b/Chapter08/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter09/Documentation/Chinese/Z2B_Chapter09.pdf b/Chapter09/Documentation/Chinese/Z2B_Chapter09.pdf index 09f6b89..4454eef 100644 Binary files a/Chapter09/Documentation/Chinese/Z2B_Chapter09.pdf and b/Chapter09/Documentation/Chinese/Z2B_Chapter09.pdf differ diff --git a/Chapter09/Documentation/Chinese/Z2B_Chapter09.pptx b/Chapter09/Documentation/Chinese/Z2B_Chapter09.pptx new file mode 100644 index 0000000..d192a8a Binary files /dev/null and b/Chapter09/Documentation/Chinese/Z2B_Chapter09.pptx differ diff --git a/Chapter09/Documentation/Espanol/Z2B_Chapter09.pdf b/Chapter09/Documentation/Espanol/Z2B_Chapter09.pdf index c1627c5..d40112d 100644 Binary files a/Chapter09/Documentation/Espanol/Z2B_Chapter09.pdf and b/Chapter09/Documentation/Espanol/Z2B_Chapter09.pdf differ diff --git a/Chapter09/Documentation/Espanol/Z2B_Chapter09.pptx b/Chapter09/Documentation/Espanol/Z2B_Chapter09.pptx new file mode 100644 index 0000000..6118a54 Binary files /dev/null and b/Chapter09/Documentation/Espanol/Z2B_Chapter09.pptx differ diff --git a/Chapter09/Documentation/Japanese/Z2B_Chapter09.pdf b/Chapter09/Documentation/Japanese/Z2B_Chapter09.pdf index a99234c..c9e84f6 100644 Binary files a/Chapter09/Documentation/Japanese/Z2B_Chapter09.pdf and b/Chapter09/Documentation/Japanese/Z2B_Chapter09.pdf differ diff --git a/Chapter09/Documentation/Japanese/Z2B_Chapter09.pptx b/Chapter09/Documentation/Japanese/Z2B_Chapter09.pptx new file mode 100644 index 0000000..6a69711 Binary files /dev/null and b/Chapter09/Documentation/Japanese/Z2B_Chapter09.pptx differ diff --git a/Chapter09/Documentation/Z2B Chapter09.pdf b/Chapter09/Documentation/Z2B Chapter09.pdf index 00a6394..42885cd 100644 Binary files a/Chapter09/Documentation/Z2B Chapter09.pdf and b/Chapter09/Documentation/Z2B Chapter09.pdf differ diff --git a/Chapter09/Documentation/answers/composer/hlcClient_complete.js b/Chapter09/Documentation/answers/composer/hlcClient_complete.js index 6d7ffab..5b909c1 100644 --- a/Chapter09/Documentation/answers/composer/hlcClient_complete.js +++ b/Chapter09/Documentation/answers/composer/hlcClient_complete.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,153 +115,153 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + console.log('Update Delivery Status'); + updateOrder = factory.newTransaction(NS, 'Delivering'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + updateOrder.deliveryStatus = req.body.delivery; + break; + case 'Delivered': + console.log('Delivered entered'); + updateOrder = factory.newTransaction(NS, 'Deliver'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -266,85 +270,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter09/Documentation/answers/js/z2b-shipper_complete.js b/Chapter09/Documentation/answers/js/z2b-shipper_complete.js index 31a20ee..37ba88b 100644 --- a/Chapter09/Documentation/answers/js/z2b-shipper_complete.js +++ b/Chapter09/Documentation/answers/js/z2b-shipper_complete.js @@ -14,66 +14,68 @@ // z2c-shipper.js -var shipperOrderDiv = "shipperOrderDiv"; +'use strict'; + +let shipperOrderDiv = 'shipperOrderDiv'; /** * load the shipper User Experience */ function loadShipperUX () { - toLoad = "shipper.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupShipper(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'shipper.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupShipper(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupShipper(page[0], port[0]);}); + } } - +/** + * + * @param {String} page - the page to load + * @param {Integer} port - the web socket to use + */ function setupShipper(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("shipper"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('shipper_messages', msgPort); - var _clear = $("#shipper_clear"); - var _list = $("#shipperOrderStatus"); - var _orderDiv = $("#"+shipperOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listShipperOrders()}); - $("#shipper").empty(); - $("#shipper").append(sh_string); - $("#shipperCompany").empty(); - $("#shipperCompany").append(providers[0].companyName); - $("#shipper").on('change', function() { - $("#shipperCompany").empty(); _orderDiv.empty(); $("#shipper_messages").empty(); - $("#shipperCompany").append(findMember($("#shipper").find(":selected").val(),shippers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('shipper'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('shipper_messages', msgPort); + let _clear = $('#shipper_clear'); + let _list = $('#shipperOrderStatus'); + let _orderDiv = $('#'+shipperOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listShipperOrders();}); + $('#shipper').empty(); + $('#shipper').append(sh_string); + $('#shipperCompany').empty(); + $('#shipperCompany').append(providers[0].companyName); + $('#shipper').on('change', function() { + $('#shipperCompany').empty(); _orderDiv.empty(); $('#shipper_messages').empty(); + $('#shipperCompany').append(findMember($('#shipper').find(':selected').val(),shippers).companyName); + }); } /** * lists all orders for the selected shipper */ function listShipperOrders() { - var options = {}; - options.id = $("#shipper").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#shipper').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#shipperOrderDiv").empty(); $("#shipperOrderDiv").append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} - else{formatShipperOrders($("#shipperOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#shipperOrderDiv').empty(); $('#shipperOrderDiv').append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} + else{formatShipperOrders($('#shipperOrderDiv'), _results.orders)} + }); } /** * used by the listOrders() function @@ -84,93 +86,93 @@ function listShipperOrders() */ function formatShipperOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; var _statusText; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + _statusText = ''; + // + // each order can have different states and the action that a shipper can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].requestShipment; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivering; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivered; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - console.log('OrderStatus not processed for: '+_arr[_idx].status); - break; - } - _button = '' - _action += ""; - console.log("shipper _action: "+_action); - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + console.log('OrderStatus not processed for: '+_arr[_idx].status); + break; + } + let _button = ''; + _action += ''; + console.log('shipper _action: '+_action); + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + console.log(_str); + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#sh_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#sh_action'+_idx).find(':selected').text(); + options.orderNo = $('#sh_order'+_idx).text(); + options.participant = $('#shipper').val(); + options.delivery = $('#delivery'+_idx).val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#sh_reason'+_idx).val();} + console.log(options); + $('#shipper_messages').prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#shipper_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - console.log(_str); - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#sh_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#sh_action"+_idx).find(":selected").text(); - options.orderNo = $("#sh_order"+_idx).text(); - options.participant = $("#shipper").val(); - options.delivery = $("#delivery"+_idx).val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#sh_reason"+_idx).val();} - console.log(options); - $("#shipper_messages").prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#shipper_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter09/HTML/CSS/pageStyles.css b/Chapter09/HTML/CSS/pageStyles.css index d6d67bf..6038b35 100755 --- a/Chapter09/HTML/CSS/pageStyles.css +++ b/Chapter09/HTML/CSS/pageStyles.css @@ -47,6 +47,17 @@ body {height: 100%} overflow: auto; } } +.strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: #5DC15D;} .provider { background-color: #8A99D3;} @@ -72,14 +83,14 @@ p.message{ } .scrollingPaneLeft{ position: fixed; - height: 85%; + height: 80%; margin-left: 1%; width: 45%; overflow: auto; } .scrollingPaneRight{ position: fixed; - height: 85%; + height: 80%; margin-left: 50%; width: 45%; overflow: auto; @@ -87,10 +98,10 @@ p.message{ .blockchain { background-color: black; position: fixed; - height: 9%; + height: 8%; margin-left: 1%; width: 95%; - top: 90%; + top: 92%; padding: 4px; overflow-x: auto; overflow-y: hidden; diff --git a/Chapter09/HTML/admin.html b/Chapter09/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter09/HTML/admin.html +++ b/Chapter09/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
-
+ \ No newline at end of file diff --git a/Chapter09/HTML/adminHelp.html b/Chapter09/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter09/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter09/HTML/favicon.ico b/Chapter09/HTML/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter09/HTML/favicon.ico and b/Chapter09/HTML/favicon.ico differ diff --git a/Chapter09/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter09/HTML/fonts/glyphicons-halflings-regular.ttf index 1413fc6..1f85312 100644 Binary files a/Chapter09/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter09/HTML/fonts/glyphicons-halflings-regular.ttf differ diff --git a/Chapter09/HTML/icons/Search.ico b/Chapter09/HTML/icons/Search.ico index e1d39ae..fd437a0 100755 Binary files a/Chapter09/HTML/icons/Search.ico and b/Chapter09/HTML/icons/Search.ico differ diff --git a/Chapter09/HTML/js/z2b-admin.js b/Chapter09/HTML/js/z2b-admin.js index c716cb8..67f421a 100644 --- a/Chapter09/HTML/js/z2b-admin.js +++ b/Chapter09/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -130,55 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter09/HTML/js/z2b-buyer.js b/Chapter09/HTML/js/z2b-buyer.js index 37f4b2c..535f938 100644 --- a/Chapter09/HTML/js/z2b-buyer.js +++ b/Chapter09/HTML/js/z2b-buyer.js @@ -14,166 +14,173 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; +'use strict'; + +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#body").empty(); - $("#body").append(page); - // update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#body').empty(); + $('#body').append(page); + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() { _orderDiv.empty(); $("#buyer_messages").empty(); $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; }); + $('#company')[0].innerText = buyers[0].companyName; + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array @@ -183,113 +190,114 @@ function listOrders() */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + })(each, _orders) + } } \ No newline at end of file diff --git a/Chapter09/HTML/js/z2b-initiate.js b/Chapter09/HTML/js/z2b-initiate.js index b566a28..290ef03 100644 --- a/Chapter09/HTML/js/z2b-initiate.js +++ b/Chapter09/HTML/js/z2b-initiate.js @@ -46,7 +46,7 @@ var orderStatus = { { // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English goMultiLingual("US_English", "index"); - // memberLoad loads the members already present in the network + // singleUX loads the members already present in the network memberLoad(); // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring getChainEvents(); diff --git a/Chapter09/HTML/js/z2b-provider.js b/Chapter09/HTML/js/z2b-provider.js index e002d77..99d667f 100644 --- a/Chapter09/HTML/js/z2b-provider.js +++ b/Chapter09/HTML/js/z2b-provider.js @@ -14,67 +14,71 @@ // z2c-provider.js -var providerOrderDiv = "providerOrderDiv"; +'use strict'; + +let providerOrderDiv = 'providerOrderDiv'; /** * load the Provider User Experience */ function loadProviderUX () { - toLoad = "provider.html"; + let toLoad = 'provider.html'; getPort(); - if (buyers.length === 0) + if (buyers.length === 0) { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupProvider(page[0], port[0]);}); } else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupProvider(page[0], port[0]);}); + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupProvider(page[0], port[0]);}); } - } - +} + +/** + * load the Provider User Experience + * @param {String} page - the name of the page to load + * @param {Integer} port - the port number to use + */ function setupProvider(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("provider"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('provider_messages', msgPort); - var _clear = $("#provider_clear"); - var _list = $("#providerOrderStatus"); - var _orderDiv = $("#"+providerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listProviderOrders()}); - $("#provider").empty(); - $("#provider").append(p_string); - $("#providerCompany").empty(); - $("#providerCompany").append(providers[0].companyName); - $("#provider").on('change', function() { - $("#providerCompany").empty(); _orderDiv.empty(); $("#provider_messages").empty(); - $("#providerCompany").append(findMember($("#provider").find(":selected").val(),providers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('provider'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('provider_messages', msgPort); + let _clear = $('#provider_clear'); + let _list = $('#providerOrderStatus'); + let _orderDiv = $('#'+providerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listProviderOrders();}); + $('#provider').empty(); + $('#provider').append(p_string); + $('#providerCompany').empty(); + $('#providerCompany').append(providers[0].companyName); + $('#provider').on('change', function() { + $('#providerCompany').empty(); _orderDiv.empty(); $('#provider_messages').empty(); + $('#providerCompany').append(findMember($('#provider').find(':selected').val(),providers).companyName); + }); } /** * lists all orders for the selected Provider */ function listProviderOrders() { - var options = {}; - options.id = $("#provider").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#provider').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#providerOrderDiv").empty(); $("#providerOrderDiv").append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} - else{formatProviderOrders($("#providerOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#providerOrderDiv').empty(); $('#providerOrderDiv').append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} + else{formatProviderOrders($('#providerOrderDiv'), _results.orders);} + }); } + /** * used by the listOrders() function * formats the orders for a Provider. Orders to be formatted are provided in the _orders array @@ -84,97 +88,97 @@ function listProviderOrders() */ function formatProviderOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let b_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + b_string = ''; + // + // each order can have different states and the action that a Provider can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += ''; - _action += ''; - b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; - break; + _date = _arr[_idx].ordered; + _action += ''; + _action += ''; + b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += ''; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= ''; + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#p_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#p_action'+_idx).find(':selected').text(); + options.orderNo = $('#p_order'+_idx).text(); + options.participant = $('#provider').val(); + options.shipper = $('#shippers'+_idx).find(':selected').val(); + if ((options.action == 'Resolve') || (options.action === 'Refund') || (options.action === 'BackOrder')) {options.reason = $('#p_reason'+_idx).val();} + console.log(options); + $('#provider_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#provider_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#p_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#p_action"+_idx).find(":selected").text(); - options.orderNo = $("#p_order"+_idx).text(); - options.participant = $("#provider").val(); - options.shipper = $("#shippers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund') || (options.action == 'BackOrder')) {options.reason = $("#p_reason"+_idx).val();} - console.log(options); - $("#provider_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#provider_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter09/HTML/js/z2b-seller.js b/Chapter09/HTML/js/z2b-seller.js index 7099a9b..ecc7209 100644 --- a/Chapter09/HTML/js/z2b-seller.js +++ b/Chapter09/HTML/js/z2b-seller.js @@ -13,167 +13,171 @@ */ // z2c-seller.js -var sellerOrderDiv = "sellerOrderDiv"; + +'use strict'; +let sellerOrderDiv = 'sellerOrderDiv'; /** - * load the administration User Experience + * load the administration Seller Experience */ function loadSellerUX () { - toLoad = "seller.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupSeller(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'seller.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupSeller(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupSeller(page[0], port[0]);}); + } } +/** + * load the administration User Experience + * @param {String} page - page to load + * @param {Integer} port - web socket port to use + */ function setupSeller(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("seller"); - msgPort = port.port; - wsDisplay('seller_messages', msgPort); - var _clear = $("#seller_clear"); - var _list = $("#sellerOrderStatus"); - var _orderDiv = $("#"+sellerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - // - // this section changes from the previous chapter, buyer changing to seller - // - _list.on('click', function(){listSellerOrders()}); - $("#seller").empty(); - $("#seller").append(s_string); - $("#sellerCompany").empty(); - $("#sellerCompany").append(sellers[0].companyName); - $("#seller").on('change', function() { - $("#sellerCompany").empty(); _orderDiv.empty(); $("#seller_messages").empty(); - $("#sellerCompany").append(findMember($("#seller").find(":selected").val(),sellers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('seller'); + msgPort = port.port; + wsDisplay('seller_messages', msgPort); + let _clear = $('#seller_clear'); + let _list = $('#sellerOrderStatus'); + let _orderDiv = $('#'+sellerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + // + // this section changes from the previous chapter, buyer changing to seller + // + _list.on('click', function(){listSellerOrders();}); + $('#seller').empty(); + $('#seller').append(s_string); + $('#sellerCompany').empty(); + $('#sellerCompany').append(sellers[0].companyName); + $('#seller').on('change', function() { + $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty(); + $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName); + }); } /** * lists all orders for the selected seller */ function listSellerOrders() { - var options = {}; - // - // seller instead of buyer - // - options.id = $("#seller").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + // + // seller instead of buyer + // + options.id= $('#seller').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} - else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)} - }); - }); + { + if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} + else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);} + }); } /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatSellerOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += ''; - break; + _date = _arr[_idx].bought; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - var _string = '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + let _string = '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - - _target.append(_str); - for (let each in _orders) + + _target.append(_str); + for (let each in _orders) {(function(_idx, _arr) - { $("#s_btn_"+_idx).on('click', function () + { $('#s_btn_'+_idx).on('click', function () { - var options = {}; - options.action = $("#s_action"+_idx).find(":selected").text(); - options.orderNo = $("#s_order"+_idx).text(); - options.participant = $("#seller").val(); - options.provider = $("#providers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#s_reason"+_idx).val();} - $("#seller_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + let options = {}; + options.action = $('#s_action'+_idx).find(':selected').text(); + options.orderNo = $('#s_order'+_idx).text(); + options.participant = $('#seller').val(); + options.provider = $('#providers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#s_reason'+_idx).val();} + $('#seller_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#seller_messages").prepend(formatMessage(_results.result)); }); + { $('#seller_messages').prepend(formatMessage(_results.result)); }); }); - })(each, _orders) - } + })(each, _orders); + } } \ No newline at end of file diff --git a/Chapter09/HTML/js/z2b-shipper.js b/Chapter09/HTML/js/z2b-shipper.js index 9513ff3..ef89904 100644 --- a/Chapter09/HTML/js/z2b-shipper.js +++ b/Chapter09/HTML/js/z2b-shipper.js @@ -14,65 +14,68 @@ // z2c-shipper.js -var shipperOrderDiv = "shipperOrderDiv"; +'use strict'; + +let shipperOrderDiv = 'shipperOrderDiv'; /** * load the shipper User Experience */ function loadShipperUX () { - toLoad = "shipper.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupShipper(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'shipper.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupShipper(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupShipper(page[0], port[0]);}); + } } - +/** + * + * @param {String} page - the page to load + * @param {Integer} port - the web socket to use + */ function setupShipper(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("shipper"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('shipper_messages', msgPort); - var _clear = $("#shipper_clear"); - var _list = $("#shipperOrderStatus"); - var _orderDiv = $("#"+shipperOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listShipperOrders()}); - $("#shipper").empty(); - $("#shipper").append(sh_string); - $("#shipperCompany").empty(); - $("#shipperCompany").append(providers[0].companyName); - $("#shipper").on('change', function() { - - }); + $('#body').empty(); + $('#body').append(page); + updatePage('shipper'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('shipper_messages', msgPort); + let _clear = $('#shipper_clear'); + let _list = $('#shipperOrderStatus'); + let _orderDiv = $('#'+shipperOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listShipperOrders();}); + $('#shipper').empty(); + $('#shipper').append(sh_string); + $('#shipperCompany').empty(); + $('#shipperCompany').append(providers[0].companyName); + $('#shipper').on('change', function() { + $('#shipperCompany').empty(); _orderDiv.empty(); $('#shipper_messages').empty(); + $('#shipperCompany').append(findMember($('#shipper').find(':selected').val(),shippers).companyName); + }); } /** * lists all orders for the selected shipper */ function listShipperOrders() { - var options = {}; - options.id = $("#shipper").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#shipper').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#shipperOrderDiv").empty(); $("#shipperOrderDiv").append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} - else{formatShipperOrders($("#shipperOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#shipperOrderDiv').empty(); $('#shipperOrderDiv').append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} + else{formatShipperOrders($('#shipperOrderDiv'), _results.orders)} + }); } /** * used by the listOrders() function @@ -83,83 +86,83 @@ function listShipperOrders() */ function formatShipperOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; var _statusText; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + _statusText = ''; + // + // each order can have different states and the action that a shipper can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.ShipRequest.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivering.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Dispute.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Resolve.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Cancelled.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Paid.code: - - break; + // ========> Your Code Goes Here <========= + break; default: - console.log('OrderStatus not processed for: '+_arr[_idx].status); - break; - } - _button = '' - _action += ""; - console.log("shipper _action: "+_action); - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + console.log('OrderStatus not processed for: '+_arr[_idx].status); + break; + } + let _button = ''; + _action += ''; + console.log('shipper _action: '+_action); + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + console.log(_str); + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#sh_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#sh_action'+_idx).find(':selected').text(); + options.orderNo = $('#sh_order'+_idx).text(); + options.participant = $('#shipper').val(); + options.delivery = $('#delivery'+_idx).val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#sh_reason'+_idx).val();} + console.log(options); + $('#shipper_messages').prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#shipper_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - console.log(_str); - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#sh_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#sh_action"+_idx).find(":selected").text(); - options.orderNo = $("#sh_order"+_idx).text(); - options.participant = $("#shipper").val(); - options.delivery = $("#delivery"+_idx).val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#sh_reason"+_idx).val();} - console.log(options); - $("#shipper_messages").prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#shipper_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter09/HTML/removeMember.html b/Chapter09/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter09/HTML/removeMember.html +++ b/Chapter09/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter09/README.pdf b/Chapter09/README.pdf index 29f4a87..afef78d 100644 Binary files a/Chapter09/README.pdf and b/Chapter09/README.pdf differ diff --git a/Chapter09/buildAndDeploy b/Chapter09/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter09/buildAndDeploy +++ b/Chapter09/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter09/controller/env.json b/Chapter09/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter09/controller/env.json +++ b/Chapter09/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter09/controller/restapi/features/composer/autoLoad.js b/Chapter09/controller/restapi/features/composer/autoLoad.js index 1f5214f..ce3d81b 100644 --- a/Chapter09/controller/restapi/features/composer/autoLoad.js +++ b/Chapter09/controller/restapi/features/composer/autoLoad.js @@ -14,62 +14,57 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter09/controller/restapi/features/composer/hlcAdmin.js b/Chapter09/controller/restapi/features/composer/hlcAdmin.js index 27b12a3..8e9e8b9 100644 --- a/Chapter09/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter09/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter09/controller/restapi/features/composer/hlcClient.js b/Chapter09/controller/restapi/features/composer/hlcClient.js index 92f5f33..53c8838 100644 --- a/Chapter09/controller/restapi/features/composer/hlcClient.js +++ b/Chapter09/controller/restapi/features/composer/hlcClient.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,147 +115,145 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - - break; - case 'Delivered': - console.log('Delivered entered'); - - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + // ========> Your Code Goes Here <========= + break; + case 'Delivered': + // ========> Your Code Goes Here <========= + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -260,85 +262,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter09/controller/restapi/features/text/ch/prompts.json b/Chapter09/controller/restapi/features/text/ch/prompts.json index 87a8ed5..5a2b598 100644 --- a/Chapter09/controller/restapi/features/text/ch/prompts.json +++ b/Chapter09/controller/restapi/features/text/ch/prompts.json @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", diff --git a/Chapter09/controller/restapi/features/text/en-UK/prompts.json b/Chapter09/controller/restapi/features/text/en-UK/prompts.json index 99158f7..c7e9622 100644 --- a/Chapter09/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter09/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "UK English", - "title": "Z2B Chapter 9", - "header": "Chapter 9: Building the Shipper User Experience", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 9", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 9. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 9: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 9, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 9, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 9, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 9", + "header":"Chapter 9: Building the Shipper User Experience", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter09/controller/restapi/features/text/en-US/prompts.json b/Chapter09/controller/restapi/features/text/en-US/prompts.json index baff7be..b1fb057 100644 --- a/Chapter09/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter09/controller/restapi/features/text/en-US/prompts.json @@ -53,7 +53,10 @@ "rm_am_api": "Add Member", "rm_am_param": "Co Name, id, Type", "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", "bc": "BlockChain", "bc_api": "API", "bc_param": "Parameters", @@ -96,8 +99,8 @@ "cd_financeco": "FinanceCo", "cd_cn": "Company Name", "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" + "cancel": "Cancel", + "submit": "Submit" }, "createOrder": { "title": "Create New Order", diff --git a/Chapter09/controller/restapi/features/text/es-LA/prompts.json b/Chapter09/controller/restapi/features/text/es-LA/prompts.json index 4b75ea2..029374f 100644 --- a/Chapter09/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter09/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 9", - "header":"Capítulo 9: Construyendo la experiencia del usuario del transportista", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 9", + "header":"Capítulo 9: Construyendo la experiencia del usuario del transportista", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter09/controller/restapi/features/text/fr/prompts.json b/Chapter09/controller/restapi/features/text/fr/prompts.json index dc7af6b..8e34484 100644 --- a/Chapter09/controller/restapi/features/text/fr/prompts.json +++ b/Chapter09/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 9", - "header":"Chapitre 9 : Construire l'experience de l'expéditeur", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 05", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { - "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", - "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { - "title":"Zero to Blockchain Chapitre 10: Le financier mondial", - "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { - "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", - "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { - "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", - "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { - "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", - "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer(0) demander le numero de commande:(1)", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 9", + "header":"Chapitre 9 : Construire l'experience de l'expéditeur", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { + "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", + "newOrder":"Créér une nouvelle commande", + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { + "title":"Zero to Blockchain Chapitre 10: Le financier mondial", + "financeCOclear":"Effacer le contenu de la fenetre", + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { + "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", + "provider_clear":"Effacer le contenu de la fenetre", + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { + "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", + "seller_clear":"Effacer le contenu de la fenetre", + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { + "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", + "shipper_clear":"Effacer le contenu de la fenetre", + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter09/controller/restapi/features/text/jp/prompts.json b/Chapter09/controller/restapi/features/text/jp/prompts.json index a11164b..6f9ef4c 100644 --- a/Chapter09/controller/restapi/features/text/jp/prompts.json +++ b/Chapter09/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 9章", - "header":"弟 9章: 荷送人ユーザー経験の構築", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟05章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟07章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 9章", + "header":"弟 9章: 荷送人ユーザー経験の構築", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter09/controller/restapi/features/text/languages.json b/Chapter09/controller/restapi/features/text/languages.json index 91b0348..8ee6b21 100644 --- a/Chapter09/controller/restapi/features/text/languages.json +++ b/Chapter09/controller/restapi/features/text/languages.json @@ -6,6 +6,6 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, - "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} + "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } \ No newline at end of file diff --git a/Chapter09/controller/restapi/features/text/pt/prompts.json b/Chapter09/controller/restapi/features/text/pt/prompts.json index 4a3c1db..40cdd12 100644 --- a/Chapter09/controller/restapi/features/text/pt/prompts.json +++ b/Chapter09/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 9", + "header":"Capítulo 9: Construindo a Experiência de Usuário Transportador", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter09/controller/restapi/router.js b/Chapter09/controller/restapi/router.js index e638725..6fa15bd 100644 --- a/Chapter09/controller/restapi/router.js +++ b/Chapter09/controller/restapi/router.js @@ -12,19 +12,19 @@ * limitations under the License. */ +'use strict'; -var express = require('express'); -var router = express.Router(); -var format = require('date-format'); +let express = require('express'); +let router = express.Router(); +let format = require('date-format'); -var multi_lingual = require('./features/multi_lingual'); -var resources = require('./features/resources'); -var getCreds = require('./features/getCredentials'); -var hlcAdmin = require('./features/composer/hlcAdmin'); -var hlcClient = require('./features/composer/hlcClient'); -var setup = require('./features/composer/autoLoad'); - -var hlcFabric = require('./features/composer/queryBlockChain'); +let multi_lingual = require('./features/multi_lingual'); +let resources = require('./features/resources'); +let getCreds = require('./features/getCredentials'); +let hlcAdmin = require('./features/composer/hlcAdmin'); +let hlcClient = require('./features/composer/hlcClient'); +let setup = require('./features/composer/autoLoad'); +let hlcFabric = require('./features/composer/queryBlockChain'); router.post('/setup/autoLoad*', setup.autoLoad); router.get('/setup/getPort*', setup.getPort); @@ -33,13 +33,29 @@ router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); router.get('/fabric/getHistory', hlcAdmin.getHistory); module.exports = router; -var count = 0; +let count = 0; +/** + * This is a request tracking function which logs to the terminal window each request coming in to the web serve and + * increments a counter to allow the requests to be sequenced. + * @param {express.req} req - the inbound request object from the client + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * + * @function + */ router.use(function(req, res, next) { - count++; - console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); - next(); // make sure we go to the next routes and don't stop here + count++; + console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); + next(); // make sure we go to the next routes and don't stop here }); +// the following get and post statements tell nodeJS what to do when a request comes in +// The request is the single quoted phrase following the get( or post( statement. +// the text at the end identifies which function in which require(d) module to implement +// These are searched in order by get/post request. +// The asterisk (*) means 'ignore anything following this point' +// which means we have to be careful about ordering these statements. +// router.get('/api/getSupportedLanguages*',multi_lingual.languages); router.get('/api/getTextLocations*',multi_lingual.locations); router.post('/api/selectedPrompts*',multi_lingual.prompts); @@ -54,7 +70,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -71,8 +86,12 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); +// router requests specific to the Buyer router.get('/composer/client/getItemTable*', hlcClient.getItemTable); router.post('/composer/client/getMyOrders*', hlcClient.getMyOrders); router.post('/composer/client/addOrder*', hlcClient.addOrder); -router.post('/composer/client/orderAction*', hlcClient.orderAction); +router.post('/composer/client/orderAction*', hlcClient.orderAction); \ No newline at end of file diff --git a/Chapter09/createArchive.sh b/Chapter09/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter09/createArchive.sh +++ b/Chapter09/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter09/deployNetwork.sh b/Chapter09/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter09/deployNetwork.sh +++ b/Chapter09/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter09/favicon.ico b/Chapter09/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter09/favicon.ico and b/Chapter09/favicon.ico differ diff --git a/Chapter09/network/dist/networkadmin.card b/Chapter09/network/dist/networkadmin.card new file mode 100644 index 0000000..88165ec Binary files /dev/null and b/Chapter09/network/dist/networkadmin.card differ diff --git a/Chapter09/network/package.json b/Chapter09/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter09/network/package.json +++ b/Chapter09/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter09/network/test/sample.js b/Chapter09/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter09/network/test/sample.js +++ b/Chapter09/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter09/package.json b/Chapter09/package.json index 1d086ff..57535e3 100644 --- a/Chapter09/package.json +++ b/Chapter09/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter09/startup.sh b/Chapter09/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter09/startup.sh +++ b/Chapter09/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter09/z2c_login b/Chapter09/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter09/z2c_login +++ b/Chapter09/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter10/Documentation/Chinese/Z2B Chapter10.pdf b/Chapter10/Documentation/Chinese/Z2B Chapter10.pdf index f440dd7..3891a54 100644 Binary files a/Chapter10/Documentation/Chinese/Z2B Chapter10.pdf and b/Chapter10/Documentation/Chinese/Z2B Chapter10.pdf differ diff --git a/Chapter10/Documentation/Chinese/Z2B Chapter10.pptx b/Chapter10/Documentation/Chinese/Z2B Chapter10.pptx new file mode 100644 index 0000000..8eeea4f Binary files /dev/null and b/Chapter10/Documentation/Chinese/Z2B Chapter10.pptx differ diff --git a/Chapter10/Documentation/Espanol/Z2B Chapter10.pdf b/Chapter10/Documentation/Espanol/Z2B Chapter10.pdf index 90797cf..cd9254b 100644 Binary files a/Chapter10/Documentation/Espanol/Z2B Chapter10.pdf and b/Chapter10/Documentation/Espanol/Z2B Chapter10.pdf differ diff --git a/Chapter10/Documentation/Espanol/Z2B Chapter10.pptx b/Chapter10/Documentation/Espanol/Z2B Chapter10.pptx new file mode 100644 index 0000000..b1b03ad Binary files /dev/null and b/Chapter10/Documentation/Espanol/Z2B Chapter10.pptx differ diff --git a/Chapter10/Documentation/Japanese/Z2B Chapter10.pdf b/Chapter10/Documentation/Japanese/Z2B Chapter10.pdf index d8cd935..1b3cbe2 100644 Binary files a/Chapter10/Documentation/Japanese/Z2B Chapter10.pdf and b/Chapter10/Documentation/Japanese/Z2B Chapter10.pdf differ diff --git a/Chapter10/Documentation/Japanese/Z2B Chapter10.pptx b/Chapter10/Documentation/Japanese/Z2B Chapter10.pptx new file mode 100644 index 0000000..c23b11e Binary files /dev/null and b/Chapter10/Documentation/Japanese/Z2B Chapter10.pptx differ diff --git a/Chapter10/Documentation/Z2B Chapter10.pdf b/Chapter10/Documentation/Z2B Chapter10.pdf index 214537b..9aad77d 100644 Binary files a/Chapter10/Documentation/Z2B Chapter10.pdf and b/Chapter10/Documentation/Z2B Chapter10.pdf differ diff --git a/Chapter10/Documentation/answers/composer/hlcClient_complete.js b/Chapter10/Documentation/answers/composer/hlcClient_complete.js index 401bf01..bc5bfb6 100644 --- a/Chapter10/Documentation/answers/composer/hlcClient_complete.js +++ b/Chapter10/Documentation/answers/composer/hlcClient_complete.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,155 +115,156 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - updateOrder = factory.newTransaction(NS, 'Pay'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + console.log('Pay entered'); + updateOrder = factory.newTransaction(NS, 'Pay'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + console.log('Update Delivery Status'); + updateOrder = factory.newTransaction(NS, 'Delivering'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + updateOrder.deliveryStatus = req.body.delivery; + break; + case 'Delivered': + console.log('Delivered entered'); + updateOrder = factory.newTransaction(NS, 'Deliver'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -268,85 +273,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter10/Documentation/answers/js/z2b-financeCo_complete.js b/Chapter10/Documentation/answers/js/z2b-financeCo_complete.js index aa1fa3d..a74a755 100644 --- a/Chapter10/Documentation/answers/js/z2b-financeCo_complete.js +++ b/Chapter10/Documentation/answers/js/z2b-financeCo_complete.js @@ -14,58 +14,63 @@ // z2c-financeCo.js -var financeCOorderDiv = "financeCOorderDiv"; -var orders = []; +'use strict'; + +let financeCOorderDiv = 'financeCOorderDiv'; +let orders = []; const financeCoID = 'easymoney@easymoneyinc.com'; -const financeCoName = 'The Global Financier'; /** * load the finance company User Experience */ function loadFinanceCoUX () { - toLoad = "financeCo.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupFinanceCo(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'financeCo.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupFinanceCo(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupFinanceCo(page[0], port[0]);}); + } } - +/** + * @param {String} page HTML page to load + * @param {Integer} port Websocket port to use + */ function setupFinanceCo(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("financeCo"); - msgPort = port.port; - wsDisplay('finance_messages', msgPort); - var _clear = $("#financeCOclear"); - var _list = $("#financeCOorderStatus"); - var _orderDiv = $("#"+financeCOorderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listFinanceOrders()}); + $('#body').empty(); + $('#body').append(page); + updatePage( 'financeCo'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('finance_messages', msgPort); + let _clear = $('#financeCOclear'); + let _list = $('#financeCOorderStatus'); + let _orderDiv = $('#'+financeCOorderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listFinanceOrders();}); } /** * lists all orders for the selected financier */ function listFinanceOrders() { - var options = {}; - options.id = financeCoID; - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = financeCoID; + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#"+financeCOorderDiv).empty(); $("#"+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} - else{orders = _results.orders; formatFinanceOrders($("#"+financeCOorderDiv), orders)} - }); - }); + { + console.log(_results.result); + console.log(_results.orders); + if (_results.orders.length < 1) {$('#'+financeCOorderDiv).empty(); $('#'+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} + else{orders = _results.orders; formatFinanceOrders($('#'+financeCOorderDiv), orders);} + }); } + /** * used by the listOrders() function * formats the orders for a financier. Orders to be formatted are provided in the _orders array @@ -75,125 +80,130 @@ function listFinanceOrders() */ function formatFinanceOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let p_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a financier can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - break; + _date = _arr[_idx].delivered; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - break; + _date = _arr[_idx].created; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - _action += '' - break; + _date = _arr[_idx].approved; + _action += ''; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - break; + _date = _arr[_idx].bought; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Refund.code: - _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; - break; + _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += '
'; - _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_arr[_idx].buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= formatDetail(_idx, _arr[_idx]); - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { - $("#f_order"+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#order"+_idx+"_b").on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#f_btn_"+_idx).on('click', function () + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + let _len = 'resource:org.acme.Z2BTestNetwork.Buyer#'.length; + let _buyer = _arr[_idx].buyer.substring(_len, _arr[_idx].buyer.length); + _str += '
'; + _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= formatDetail(_idx, _arr[_idx]); + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) { - var options = {}; - options.action = $("#f_action"+_idx).find(":selected").text(); - options.orderNo = $("#f_order"+_idx).text(); - options.participant = financeCoID; - $("#finance_messages").prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#finance_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + $('#f_order'+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#order'+_idx+'_b').on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#f_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#f_action'+_idx).find(':selected').text(); + options.orderNo = $('#f_order'+_idx).text(); + options.participant = financeCoID; + console.log(options); + $('#finance_messages').prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#finance_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); + } } /** * format the accordian with the details for this order */ function formatDetail(_cur, _order) { - var _out = '
'; - _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; - _out += ''; - _out += ''; - _out += (_order.cancelled === "") ? '' : ''; - _out += (_order.bought === "") ? '' : ''; - _out += (_order.ordered === "") ? '' : ''; - _out += (_order.dateBackordered === "") ? '' : ''; - _out += (_order.requestShipment === "") ? '' : ''; - _out += (_order.delivering === "") ? '' : ''; - _out += (_order.delivered === "") ? '' : ''; - _out += (_order.paymentRequested === "") ? '' : ''; - _out += (_order.disputeOpened === "") ? '' : ''; - if (_order.disputeResolved === "") - { - if (_order.disputeOpened === "") - {_out += '';} + console.log('['+_cur+'] is ',_order); + let _out = '
'; + _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; + _out += '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
'; + _out += ''; + _out += (_order.cancelled === '') ? '' : ''; + _out += (_order.bought === '') ? '' : ''; + _out += (_order.ordered === '') ? '' : ''; + _out += (_order.dateBackordered === '') ? '' : ''; + _out += (_order.requestShipment === '') ? '' : ''; + _out += (_order.delivering === '') ? '' : ''; + _out += (_order.delivered === '') ? '' : ''; + _out += (_order.paymentRequested === '') ? '' : ''; + _out += (_order.disputeOpened === '') ? '' : ''; + if (_order.disputeResolved === '') + { + if (_order.disputeOpened === '') + {_out += '';} + else + {_out += '';} + } else - {_out += '';} - } - else - {_out +='';} - _out += (_order.orderRefunded === "") ? '' : ''; - _out += (_order.approved === "") ? '' : ''; - _out += (_order.paid === "") ? '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
Dispute ResolvedDispute is Unresolved
Dispute ResolvedDispute is Unresolved
Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'
Refund?(No Refund in Process)
Refund?'+_order.orderRefunded+''+_order.refund+'
Payment Approved(No Approval from Buyer)
Payment Approved'+_order.buyer+''+_order.approved+'
Paid(UnPaid)
' : 'Paid'+_order.financeCo+''+_order.paid+'
'; - return _out; + {_out +='Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'';} + _out += (_order.orderRefunded === '') ? 'Refund?(No Refund in Process)' : 'Refund?'+_order.orderRefunded+''+_order.refund+''; + _out += (_order.approved === '') ? 'Payment Approved(No Approval from Buyer)' : 'Payment Approved'+_order.buyer+''+_order.approved+''; + _out += (_order.paid === '') ? 'Paid(UnPaid)' : 'Paid'+_order.financeCo+''+_order.paid+''; + return _out; } diff --git a/Chapter10/HTML/CSS/pageStyles.css b/Chapter10/HTML/CSS/pageStyles.css index a2a071e..ea6b818 100755 --- a/Chapter10/HTML/CSS/pageStyles.css +++ b/Chapter10/HTML/CSS/pageStyles.css @@ -75,6 +75,17 @@ body {height: 100%} overflow: auto; } } +.strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: #5DC15D;} .provider { background-color: #8A99D3;} diff --git a/Chapter10/HTML/admin.html b/Chapter10/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter10/HTML/admin.html +++ b/Chapter10/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
- + \ No newline at end of file diff --git a/Chapter10/HTML/adminHelp.html b/Chapter10/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter10/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter10/HTML/favicon.ico b/Chapter10/HTML/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter10/HTML/favicon.ico and b/Chapter10/HTML/favicon.ico differ diff --git a/Chapter10/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter10/HTML/fonts/glyphicons-halflings-regular.ttf index 1413fc6..1f85312 100644 Binary files a/Chapter10/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter10/HTML/fonts/glyphicons-halflings-regular.ttf differ diff --git a/Chapter10/HTML/icons/Search.ico b/Chapter10/HTML/icons/Search.ico index e1d39ae..fd437a0 100755 Binary files a/Chapter10/HTML/icons/Search.ico and b/Chapter10/HTML/icons/Search.ico differ diff --git a/Chapter10/HTML/js/z2b-admin.js b/Chapter10/HTML/js/z2b-admin.js index c716cb8..67f421a 100644 --- a/Chapter10/HTML/js/z2b-admin.js +++ b/Chapter10/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -130,55 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter10/HTML/js/z2b-buyer.js b/Chapter10/HTML/js/z2b-buyer.js index 37f4b2c..535f938 100644 --- a/Chapter10/HTML/js/z2b-buyer.js +++ b/Chapter10/HTML/js/z2b-buyer.js @@ -14,166 +14,173 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; +'use strict'; + +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#body").empty(); - $("#body").append(page); - // update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#body').empty(); + $('#body').append(page); + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() { _orderDiv.empty(); $("#buyer_messages").empty(); $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; }); + $('#company')[0].innerText = buyers[0].companyName; + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array @@ -183,113 +190,114 @@ function listOrders() */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + })(each, _orders) + } } \ No newline at end of file diff --git a/Chapter10/HTML/js/z2b-financeCo.js b/Chapter10/HTML/js/z2b-financeCo.js index de9eee2..64355a0 100644 --- a/Chapter10/HTML/js/z2b-financeCo.js +++ b/Chapter10/HTML/js/z2b-financeCo.js @@ -14,58 +14,63 @@ // z2c-financeCo.js -var financeCOorderDiv = "financeCOorderDiv"; -var orders = []; +'use strict'; + +let financeCOorderDiv = 'financeCOorderDiv'; +let orders = []; const financeCoID = 'easymoney@easymoneyinc.com'; -const financeCoName = 'The Global Financier'; /** * load the finance company User Experience */ function loadFinanceCoUX () { - toLoad = "financeCo.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupFinanceCo(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'financeCo.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupFinanceCo(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupFinanceCo(page[0], port[0]);}); + } } - +/** + * @param {String} page HTML page to load + * @param {Integer} port Websocket port to use + */ function setupFinanceCo(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("financeCo"); - msgPort = port.port; - wsDisplay('finance_messages', msgPort); - var _clear = $("#financeCOclear"); - var _list = $("#financeCOorderStatus"); - var _orderDiv = $("#"+financeCOorderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listFinanceOrders()}); + $('#body').empty(); + $('#body').append(page); + updatePage( 'financeCo'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('finance_messages', msgPort); + let _clear = $('#financeCOclear'); + let _list = $('#financeCOorderStatus'); + let _orderDiv = $('#'+financeCOorderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listFinanceOrders();}); } /** * lists all orders for the selected financier */ function listFinanceOrders() { - var options = {}; - options.id = financeCoID; - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = financeCoID; + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#"+financeCOorderDiv).empty(); $("#"+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} - else{orders = _results.orders; formatFinanceOrders($("#"+financeCOorderDiv), orders)} - }); - }); + { + console.log(_results.result); + console.log(_results.orders); + if (_results.orders.length < 1) {$('#'+financeCOorderDiv).empty(); $('#'+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} + else{orders = _results.orders; formatFinanceOrders($('#'+financeCOorderDiv), orders);} + }); } + /** * used by the listOrders() function * formats the orders for a financier. Orders to be formatted are provided in the _orders array @@ -75,124 +80,127 @@ function listFinanceOrders() */ function formatFinanceOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let p_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a financier can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Dispute.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Resolve.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Created.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Cancelled.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Backordered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.ShipRequest.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Authorize.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Bought.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Delivering.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Ordered.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Refund.code: - - break; + // ========> Your Code Goes Here <========= + break; case orderStatus.Paid.code: - - break; + // ========> Your Code Goes Here <========= + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += '
'; - _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_arr[_idx].buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= formatDetail(_idx, _arr[_idx]); - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { - $("#f_order"+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#order"+_idx+"_b").on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#f_btn_"+_idx).on('click', function () + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'; + _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_arr[_idx].buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= formatDetail(_idx, _arr[_idx]); + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) { - var options = {}; - options.action = $("#f_action"+_idx).find(":selected").text(); - options.orderNo = $("#f_order"+_idx).text(); - options.participant = financeCoID; - $("#finance_messages").prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#finance_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + $('#f_order'+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#order'+_idx+'_b').on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#f_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#f_action'+_idx).find(':selected').text(); + options.orderNo = $('#f_order'+_idx).text(); + options.participant = financeCoID; + console.log(options); + $('#finance_messages').prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#finance_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); + } } /** * format the accordian with the details for this order */ function formatDetail(_cur, _order) { - var _out = '
'; - _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; - _out += ''; - _out += ''; - _out += (_order.cancelled === "") ? '' : ''; - _out += (_order.bought === "") ? '' : ''; - _out += (_order.ordered === "") ? '' : ''; - _out += (_order.dateBackordered === "") ? '' : ''; - _out += (_order.requestShipment === "") ? '' : ''; - _out += (_order.delivering === "") ? '' : ''; - _out += (_order.delivered === "") ? '' : ''; - _out += (_order.paymentRequested === "") ? '' : ''; - _out += (_order.disputeOpened === "") ? '' : ''; - if (_order.disputeResolved === "") - { - if (_order.disputeOpened === "") - {_out += '';} + console.log('['+_cur+'] is ',_order); + let _out = '
'; + _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; + _out += '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
'; + _out += ''; + _out += (_order.cancelled === '') ? '' : ''; + _out += (_order.bought === '') ? '' : ''; + _out += (_order.ordered === '') ? '' : ''; + _out += (_order.dateBackordered === '') ? '' : ''; + _out += (_order.requestShipment === '') ? '' : ''; + _out += (_order.delivering === '') ? '' : ''; + _out += (_order.delivered === '') ? '' : ''; + _out += (_order.paymentRequested === '') ? '' : ''; + _out += (_order.disputeOpened === '') ? '' : ''; + if (_order.disputeResolved === '') + { + if (_order.disputeOpened === '') + {_out += '';} + else + {_out += '';} + } else - {_out += '';} - } - else - {_out +='';} - _out += (_order.orderRefunded === "") ? '' : ''; - _out += (_order.approved === "") ? '' : ''; - _out += (_order.paid === "") ? '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
Dispute ResolvedDispute is Unresolved
Dispute ResolvedDispute is Unresolved
Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'
Refund?(No Refund in Process)
Refund?'+_order.orderRefunded+''+_order.refund+'
Payment Approved(No Approval from Buyer)
Payment Approved'+_order.buyer+''+_order.approved+'
Paid(UnPaid)
' : 'Paid'+_order.financeCo+''+_order.paid+''; - return _out; + {_out +='Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'';} + _out += (_order.orderRefunded === '') ? 'Refund?(No Refund in Process)' : 'Refund?'+_order.orderRefunded+''+_order.refund+''; + _out += (_order.approved === '') ? 'Payment Approved(No Approval from Buyer)' : 'Payment Approved'+_order.buyer+''+_order.approved+''; + _out += (_order.paid === '') ? 'Paid(UnPaid)' : 'Paid'+_order.financeCo+''+_order.paid+''; + return _out; } diff --git a/Chapter10/HTML/js/z2b-initiate.js b/Chapter10/HTML/js/z2b-initiate.js index b566a28..290ef03 100644 --- a/Chapter10/HTML/js/z2b-initiate.js +++ b/Chapter10/HTML/js/z2b-initiate.js @@ -46,7 +46,7 @@ var orderStatus = { { // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English goMultiLingual("US_English", "index"); - // memberLoad loads the members already present in the network + // singleUX loads the members already present in the network memberLoad(); // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring getChainEvents(); diff --git a/Chapter10/HTML/js/z2b-provider.js b/Chapter10/HTML/js/z2b-provider.js index e002d77..99d667f 100644 --- a/Chapter10/HTML/js/z2b-provider.js +++ b/Chapter10/HTML/js/z2b-provider.js @@ -14,67 +14,71 @@ // z2c-provider.js -var providerOrderDiv = "providerOrderDiv"; +'use strict'; + +let providerOrderDiv = 'providerOrderDiv'; /** * load the Provider User Experience */ function loadProviderUX () { - toLoad = "provider.html"; + let toLoad = 'provider.html'; getPort(); - if (buyers.length === 0) + if (buyers.length === 0) { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupProvider(page[0], port[0]);}); } else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupProvider(page[0], port[0]);}); + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupProvider(page[0], port[0]);}); } - } - +} + +/** + * load the Provider User Experience + * @param {String} page - the name of the page to load + * @param {Integer} port - the port number to use + */ function setupProvider(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("provider"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('provider_messages', msgPort); - var _clear = $("#provider_clear"); - var _list = $("#providerOrderStatus"); - var _orderDiv = $("#"+providerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listProviderOrders()}); - $("#provider").empty(); - $("#provider").append(p_string); - $("#providerCompany").empty(); - $("#providerCompany").append(providers[0].companyName); - $("#provider").on('change', function() { - $("#providerCompany").empty(); _orderDiv.empty(); $("#provider_messages").empty(); - $("#providerCompany").append(findMember($("#provider").find(":selected").val(),providers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('provider'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('provider_messages', msgPort); + let _clear = $('#provider_clear'); + let _list = $('#providerOrderStatus'); + let _orderDiv = $('#'+providerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listProviderOrders();}); + $('#provider').empty(); + $('#provider').append(p_string); + $('#providerCompany').empty(); + $('#providerCompany').append(providers[0].companyName); + $('#provider').on('change', function() { + $('#providerCompany').empty(); _orderDiv.empty(); $('#provider_messages').empty(); + $('#providerCompany').append(findMember($('#provider').find(':selected').val(),providers).companyName); + }); } /** * lists all orders for the selected Provider */ function listProviderOrders() { - var options = {}; - options.id = $("#provider").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#provider').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#providerOrderDiv").empty(); $("#providerOrderDiv").append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} - else{formatProviderOrders($("#providerOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#providerOrderDiv').empty(); $('#providerOrderDiv').append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} + else{formatProviderOrders($('#providerOrderDiv'), _results.orders);} + }); } + /** * used by the listOrders() function * formats the orders for a Provider. Orders to be formatted are provided in the _orders array @@ -84,97 +88,97 @@ function listProviderOrders() */ function formatProviderOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let b_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + b_string = ''; + // + // each order can have different states and the action that a Provider can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += ''; - _action += ''; - b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; - break; + _date = _arr[_idx].ordered; + _action += ''; + _action += ''; + b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += ''; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= ''; + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#p_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#p_action'+_idx).find(':selected').text(); + options.orderNo = $('#p_order'+_idx).text(); + options.participant = $('#provider').val(); + options.shipper = $('#shippers'+_idx).find(':selected').val(); + if ((options.action == 'Resolve') || (options.action === 'Refund') || (options.action === 'BackOrder')) {options.reason = $('#p_reason'+_idx).val();} + console.log(options); + $('#provider_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#provider_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#p_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#p_action"+_idx).find(":selected").text(); - options.orderNo = $("#p_order"+_idx).text(); - options.participant = $("#provider").val(); - options.shipper = $("#shippers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund') || (options.action == 'BackOrder')) {options.reason = $("#p_reason"+_idx).val();} - console.log(options); - $("#provider_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#provider_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter10/HTML/js/z2b-seller.js b/Chapter10/HTML/js/z2b-seller.js index 7099a9b..ecc7209 100644 --- a/Chapter10/HTML/js/z2b-seller.js +++ b/Chapter10/HTML/js/z2b-seller.js @@ -13,167 +13,171 @@ */ // z2c-seller.js -var sellerOrderDiv = "sellerOrderDiv"; + +'use strict'; +let sellerOrderDiv = 'sellerOrderDiv'; /** - * load the administration User Experience + * load the administration Seller Experience */ function loadSellerUX () { - toLoad = "seller.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupSeller(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'seller.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupSeller(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupSeller(page[0], port[0]);}); + } } +/** + * load the administration User Experience + * @param {String} page - page to load + * @param {Integer} port - web socket port to use + */ function setupSeller(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("seller"); - msgPort = port.port; - wsDisplay('seller_messages', msgPort); - var _clear = $("#seller_clear"); - var _list = $("#sellerOrderStatus"); - var _orderDiv = $("#"+sellerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - // - // this section changes from the previous chapter, buyer changing to seller - // - _list.on('click', function(){listSellerOrders()}); - $("#seller").empty(); - $("#seller").append(s_string); - $("#sellerCompany").empty(); - $("#sellerCompany").append(sellers[0].companyName); - $("#seller").on('change', function() { - $("#sellerCompany").empty(); _orderDiv.empty(); $("#seller_messages").empty(); - $("#sellerCompany").append(findMember($("#seller").find(":selected").val(),sellers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('seller'); + msgPort = port.port; + wsDisplay('seller_messages', msgPort); + let _clear = $('#seller_clear'); + let _list = $('#sellerOrderStatus'); + let _orderDiv = $('#'+sellerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + // + // this section changes from the previous chapter, buyer changing to seller + // + _list.on('click', function(){listSellerOrders();}); + $('#seller').empty(); + $('#seller').append(s_string); + $('#sellerCompany').empty(); + $('#sellerCompany').append(sellers[0].companyName); + $('#seller').on('change', function() { + $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty(); + $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName); + }); } /** * lists all orders for the selected seller */ function listSellerOrders() { - var options = {}; - // - // seller instead of buyer - // - options.id = $("#seller").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + // + // seller instead of buyer + // + options.id= $('#seller').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} - else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)} - }); - }); + { + if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} + else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);} + }); } /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatSellerOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += ''; - break; + _date = _arr[_idx].bought; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - var _string = '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + let _string = '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - - _target.append(_str); - for (let each in _orders) + + _target.append(_str); + for (let each in _orders) {(function(_idx, _arr) - { $("#s_btn_"+_idx).on('click', function () + { $('#s_btn_'+_idx).on('click', function () { - var options = {}; - options.action = $("#s_action"+_idx).find(":selected").text(); - options.orderNo = $("#s_order"+_idx).text(); - options.participant = $("#seller").val(); - options.provider = $("#providers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#s_reason"+_idx).val();} - $("#seller_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + let options = {}; + options.action = $('#s_action'+_idx).find(':selected').text(); + options.orderNo = $('#s_order'+_idx).text(); + options.participant = $('#seller').val(); + options.provider = $('#providers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#s_reason'+_idx).val();} + $('#seller_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#seller_messages").prepend(formatMessage(_results.result)); }); + { $('#seller_messages').prepend(formatMessage(_results.result)); }); }); - })(each, _orders) - } + })(each, _orders); + } } \ No newline at end of file diff --git a/Chapter10/HTML/js/z2b-shipper.js b/Chapter10/HTML/js/z2b-shipper.js index 31a20ee..37ba88b 100644 --- a/Chapter10/HTML/js/z2b-shipper.js +++ b/Chapter10/HTML/js/z2b-shipper.js @@ -14,66 +14,68 @@ // z2c-shipper.js -var shipperOrderDiv = "shipperOrderDiv"; +'use strict'; + +let shipperOrderDiv = 'shipperOrderDiv'; /** * load the shipper User Experience */ function loadShipperUX () { - toLoad = "shipper.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupShipper(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'shipper.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupShipper(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupShipper(page[0], port[0]);}); + } } - +/** + * + * @param {String} page - the page to load + * @param {Integer} port - the web socket to use + */ function setupShipper(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("shipper"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('shipper_messages', msgPort); - var _clear = $("#shipper_clear"); - var _list = $("#shipperOrderStatus"); - var _orderDiv = $("#"+shipperOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listShipperOrders()}); - $("#shipper").empty(); - $("#shipper").append(sh_string); - $("#shipperCompany").empty(); - $("#shipperCompany").append(providers[0].companyName); - $("#shipper").on('change', function() { - $("#shipperCompany").empty(); _orderDiv.empty(); $("#shipper_messages").empty(); - $("#shipperCompany").append(findMember($("#shipper").find(":selected").val(),shippers).companyName); - }); + $('#body').empty(); + $('#body').append(page); + updatePage('shipper'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('shipper_messages', msgPort); + let _clear = $('#shipper_clear'); + let _list = $('#shipperOrderStatus'); + let _orderDiv = $('#'+shipperOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listShipperOrders();}); + $('#shipper').empty(); + $('#shipper').append(sh_string); + $('#shipperCompany').empty(); + $('#shipperCompany').append(providers[0].companyName); + $('#shipper').on('change', function() { + $('#shipperCompany').empty(); _orderDiv.empty(); $('#shipper_messages').empty(); + $('#shipperCompany').append(findMember($('#shipper').find(':selected').val(),shippers).companyName); + }); } /** * lists all orders for the selected shipper */ function listShipperOrders() { - var options = {}; - options.id = $("#shipper").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#shipper').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#shipperOrderDiv").empty(); $("#shipperOrderDiv").append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} - else{formatShipperOrders($("#shipperOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#shipperOrderDiv').empty(); $('#shipperOrderDiv').append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} + else{formatShipperOrders($('#shipperOrderDiv'), _results.orders)} + }); } /** * used by the listOrders() function @@ -84,93 +86,93 @@ function listShipperOrders() */ function formatShipperOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; var _statusText; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + _statusText = ''; + // + // each order can have different states and the action that a shipper can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].requestShipment; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivering; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivered; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - console.log('OrderStatus not processed for: '+_arr[_idx].status); - break; - } - _button = '' - _action += ""; - console.log("shipper _action: "+_action); - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + console.log('OrderStatus not processed for: '+_arr[_idx].status); + break; + } + let _button = ''; + _action += ''; + console.log('shipper _action: '+_action); + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + console.log(_str); + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#sh_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#sh_action'+_idx).find(':selected').text(); + options.orderNo = $('#sh_order'+_idx).text(); + options.participant = $('#shipper').val(); + options.delivery = $('#delivery'+_idx).val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#sh_reason'+_idx).val();} + console.log(options); + $('#shipper_messages').prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#shipper_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - console.log(_str); - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#sh_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#sh_action"+_idx).find(":selected").text(); - options.orderNo = $("#sh_order"+_idx).text(); - options.participant = $("#shipper").val(); - options.delivery = $("#delivery"+_idx).val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#sh_reason"+_idx).val();} - console.log(options); - $("#shipper_messages").prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#shipper_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter10/HTML/removeMember.html b/Chapter10/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter10/HTML/removeMember.html +++ b/Chapter10/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter10/buildAndDeploy b/Chapter10/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter10/buildAndDeploy +++ b/Chapter10/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter10/controller/env.json b/Chapter10/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter10/controller/env.json +++ b/Chapter10/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter10/controller/restapi/features/composer/autoLoad.js b/Chapter10/controller/restapi/features/composer/autoLoad.js index 1f5214f..ce3d81b 100644 --- a/Chapter10/controller/restapi/features/composer/autoLoad.js +++ b/Chapter10/controller/restapi/features/composer/autoLoad.js @@ -14,62 +14,57 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter10/controller/restapi/features/composer/hlcAdmin.js b/Chapter10/controller/restapi/features/composer/hlcAdmin.js index 27b12a3..8e9e8b9 100644 --- a/Chapter10/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter10/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter10/controller/restapi/features/composer/hlcClient.js b/Chapter10/controller/restapi/features/composer/hlcClient.js index 6d7ffab..7a4d46f 100644 --- a/Chapter10/controller/restapi/features/composer/hlcClient.js +++ b/Chapter10/controller/restapi/features/composer/hlcClient.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,153 +115,153 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + // ========> Your Code Goes Here <========= + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + console.log('Update Delivery Status'); + updateOrder = factory.newTransaction(NS, 'Delivering'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + updateOrder.deliveryStatus = req.body.delivery; + break; + case 'Delivered': + console.log('Delivered entered'); + updateOrder = factory.newTransaction(NS, 'Deliver'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -266,85 +270,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter10/controller/restapi/features/text/ch/prompts.json b/Chapter10/controller/restapi/features/text/ch/prompts.json index fb36aae..c56be96 100644 --- a/Chapter10/controller/restapi/features/text/ch/prompts.json +++ b/Chapter10/controller/restapi/features/text/ch/prompts.json @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", diff --git a/Chapter10/controller/restapi/features/text/en-UK/prompts.json b/Chapter10/controller/restapi/features/text/en-UK/prompts.json index 75a8b81..fb88e80 100644 --- a/Chapter10/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter10/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "US English", - "title": "Z2B Chapter 10", - "header": "Chapter 10: Building the Finance Company User Experience", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 10", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 10. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 10: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 10, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 10, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 10, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 10", + "header":"Chapter 10: Building the Finance Company User Experience", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter10/controller/restapi/features/text/en-US/prompts.json b/Chapter10/controller/restapi/features/text/en-US/prompts.json index 75a8b81..3a4a713 100644 --- a/Chapter10/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter10/controller/restapi/features/text/en-US/prompts.json @@ -53,7 +53,10 @@ "rm_am_api": "Add Member", "rm_am_param": "Co Name, id, Type", "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", "bc": "BlockChain", "bc_api": "API", "bc_param": "Parameters", @@ -96,8 +99,8 @@ "cd_financeco": "FinanceCo", "cd_cn": "Company Name", "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" + "cancel": "Cancel", + "submit": "Submit" }, "createOrder": { "title": "Create New Order", diff --git a/Chapter10/controller/restapi/features/text/es-LA/prompts.json b/Chapter10/controller/restapi/features/text/es-LA/prompts.json index 6876b4c..2ad5b26 100644 --- a/Chapter10/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter10/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 10", - "header":"Capítulo 10: Construyendo la experiencia del usuario de la companía financiera", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 10", + "header":"Capítulo 10: Construyendo la experiencia del usuario de la companía financiera", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter10/controller/restapi/features/text/fr/prompts.json b/Chapter10/controller/restapi/features/text/fr/prompts.json index f17fe85..0c660c3 100644 --- a/Chapter10/controller/restapi/features/text/fr/prompts.json +++ b/Chapter10/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 10", - "header":"Chapitre 10 : Construire l'experience du financier", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 05", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { - "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", - "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { - "title":"Zero to Blockchain Chapitre 10: Le financier mondial", - "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { - "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", - "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { - "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", - "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { - "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", - "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer(0) demander le numero de commande:(1)", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 10", + "header":"Chapitre 10 : Construire l'experience du financier", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { + "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", + "newOrder":"Créér une nouvelle commande", + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { + "title":"Zero to Blockchain Chapitre 10: Le financier mondial", + "financeCOclear":"Effacer le contenu de la fenetre", + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { + "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", + "provider_clear":"Effacer le contenu de la fenetre", + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { + "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", + "seller_clear":"Effacer le contenu de la fenetre", + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { + "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", + "shipper_clear":"Effacer le contenu de la fenetre", + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter10/controller/restapi/features/text/jp/prompts.json b/Chapter10/controller/restapi/features/text/jp/prompts.json index 0d39cef..84b94d4 100644 --- a/Chapter10/controller/restapi/features/text/jp/prompts.json +++ b/Chapter10/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 10章", - "header":"弟 10章: 財務会社ユーザーエクスペリエンスの構築", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟05章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟07章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 10章", + "header":"弟 10章: 財務会社ユーザーエクスペリエンスの構築", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter10/controller/restapi/features/text/languages.json b/Chapter10/controller/restapi/features/text/languages.json index 91b0348..8ee6b21 100644 --- a/Chapter10/controller/restapi/features/text/languages.json +++ b/Chapter10/controller/restapi/features/text/languages.json @@ -6,6 +6,6 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, - "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} + "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } \ No newline at end of file diff --git a/Chapter10/controller/restapi/features/text/pt/prompts.json b/Chapter10/controller/restapi/features/text/pt/prompts.json index 4a3c1db..a698cf7 100644 --- a/Chapter10/controller/restapi/features/text/pt/prompts.json +++ b/Chapter10/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 10", + "header":"Capítulo 10: Construindo a Experiência de Usuário da Empresa Financeira", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter10/controller/restapi/router.js b/Chapter10/controller/restapi/router.js index 931a9e2..6fa15bd 100644 --- a/Chapter10/controller/restapi/router.js +++ b/Chapter10/controller/restapi/router.js @@ -12,27 +12,50 @@ * limitations under the License. */ +'use strict'; -var express = require('express'); -var router = express.Router(); -var format = require('date-format'); +let express = require('express'); +let router = express.Router(); +let format = require('date-format'); -var multi_lingual = require('./features/multi_lingual'); -var resources = require('./features/resources'); -var getCreds = require('./features/getCredentials'); -var hlcAdmin = require('./features/composer/hlcAdmin'); -var hlcClient = require('./features/composer/hlcClient'); -var hlcFabric = require('./features/composer/queryBlockChain'); -var setup = require('./features/composer/autoLoad'); +let multi_lingual = require('./features/multi_lingual'); +let resources = require('./features/resources'); +let getCreds = require('./features/getCredentials'); +let hlcAdmin = require('./features/composer/hlcAdmin'); +let hlcClient = require('./features/composer/hlcClient'); +let setup = require('./features/composer/autoLoad'); +let hlcFabric = require('./features/composer/queryBlockChain'); +router.post('/setup/autoLoad*', setup.autoLoad); +router.get('/setup/getPort*', setup.getPort); + +router.get('/fabric/getChainInfo', hlcFabric.getChainInfo); +router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); +router.get('/fabric/getHistory', hlcAdmin.getHistory); module.exports = router; -var count = 0; +let count = 0; +/** + * This is a request tracking function which logs to the terminal window each request coming in to the web serve and + * increments a counter to allow the requests to be sequenced. + * @param {express.req} req - the inbound request object from the client + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * + * @function + */ router.use(function(req, res, next) { - count++; - console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); - next(); // make sure we go to the next routes and don't stop here + count++; + console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); + next(); // make sure we go to the next routes and don't stop here }); +// the following get and post statements tell nodeJS what to do when a request comes in +// The request is the single quoted phrase following the get( or post( statement. +// the text at the end identifies which function in which require(d) module to implement +// These are searched in order by get/post request. +// The asterisk (*) means 'ignore anything following this point' +// which means we have to be careful about ordering these statements. +// router.get('/api/getSupportedLanguages*',multi_lingual.languages); router.get('/api/getTextLocations*',multi_lingual.locations); router.post('/api/selectedPrompts*',multi_lingual.prompts); @@ -47,7 +70,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -64,15 +86,12 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); -router.post('/setup/autoLoad*', setup.autoLoad); -router.get('/setup/getPort*', setup.getPort); - +// router requests specific to the Buyer router.get('/composer/client/getItemTable*', hlcClient.getItemTable); router.post('/composer/client/getMyOrders*', hlcClient.getMyOrders); router.post('/composer/client/addOrder*', hlcClient.addOrder); -router.post('/composer/client/orderAction*', hlcClient.orderAction); - -router.get('/fabric/getChainInfo', hlcFabric.getChainInfo); -router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); -router.get('/fabric/getHistory', hlcAdmin.getHistory); +router.post('/composer/client/orderAction*', hlcClient.orderAction); \ No newline at end of file diff --git a/Chapter10/createArchive.sh b/Chapter10/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter10/createArchive.sh +++ b/Chapter10/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter10/create_composer_docs.sh b/Chapter10/create_composer_docs.sh new file mode 100755 index 0000000..35e56da --- /dev/null +++ b/Chapter10/create_composer_docs.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +. ../common_OSX.sh + +CHAPTER_DIR="" +DIR="" +REPO_DIR="" +ADMIN_DIR="node_modules/composer-admin" +CLIENT_DIR="node_modules/composer-client" +CLI_DIR="node_modules/composer-cli" +COMMON_DIR="node_modules/composer-common" +HLFV1_DIR="node_modules/composer-connector-hlfv1" +RUNTIME_DIR="node_modules/composer-runtime" +declare -a elements=("${ADMIN_DIR}" "$CLIENT_DIR" "${COMMON_DIR}" "${HLFV1_DIR}" "${RUNTIME_DIR}") +declare -a folders=('Admin' 'Client' 'Common' 'hlfv1' 'Runtime') + + +# get current folder +showStep "getting current directory path" +getCurrent +CHAPTER_DIR=$DIR +showStep "Chapter dir is: ${CHAPTER_DIR}" +for i in "${elements[@]}" +do +# switch to folder + showStep "Changing to ${i}" + cd "${i}" + pwd +# generate docs + showStep "Generating Documentation" + if [ ! -e "jsdoc.json" ]; then + cp jsdoc.conf jsdoc.json + fi + jsdoc --pedantic --recurse -c jsdoc.json + cd ../../ +done + +# get current folder -1 + showStep "getting repo root folder" + cd ../ + pwd + getCurrent + REPO_DIR=$DIR + showStep "repo dir is: ${REPO_DIR}" + +# remove old folders + showStep "Removing old documentation folders" + cd Composer_Docs + pwd + for i in "${folders[@]}" + do + # switch to folder + showStep "removing old docs in ${i}" + rm -rf "${i}" + mkdir "${i}" + done +# copy new content + showStep "copying new content from node_modules in ${CHAPTER_DIR} to Composer_Docs in ${pwd}" + pwd + count=${#elements[@]} + for i in `seq 1 $count` + do + showStep "cp -R ${CHAPTER_DIR}/${elements[$i-1]}/out/ ${folders[$i-1]}" + cp -R ${CHAPTER_DIR}/${elements[$i-1]}/out/ ${folders[$i-1]} + done +# display message on how to access documentation + showStep "Hyperledger Composer API documentation has been generated for your current version of Composer. + You can access this information by navigating to the ${GREEN}Composer_Docs${RESET} folder in your repo + and opening the ${GREEN}index.html${RESET} file located there in your favorite browser" \ No newline at end of file diff --git a/Chapter10/deployNetwork.sh b/Chapter10/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter10/deployNetwork.sh +++ b/Chapter10/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter10/favicon.ico b/Chapter10/favicon.ico new file mode 100755 index 0000000..fc9e25d Binary files /dev/null and b/Chapter10/favicon.ico differ diff --git a/Chapter10/network/dist/networkadmin.card b/Chapter10/network/dist/networkadmin.card new file mode 100644 index 0000000..9177eaa Binary files /dev/null and b/Chapter10/network/dist/networkadmin.card differ diff --git a/Chapter10/network/package.json b/Chapter10/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter10/network/package.json +++ b/Chapter10/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter10/network/permissions.acl b/Chapter10/network/permissions.acl index 0a57f6a..1457cc5 100644 --- a/Chapter10/network/permissions.acl +++ b/Chapter10/network/permissions.acl @@ -8,8 +8,11 @@ rule AllAccess { action: ALLOW } */ + /** -* added to support composer V0.14 +* Added to support V0.14 breaking changes +* +*/ rule NetworkAdminUser { description: "Grant business network administrators full access to user resources" participant: "org.hyperledger.composer.system.NetworkAdmin" @@ -17,9 +20,7 @@ rule NetworkAdminUser { resource: "**" action: ALLOW } -*/ -/** -* added to support composer V0.14 + rule NetworkAdminSystem { description: "Grant business network administrators full access to system resources" participant: "org.hyperledger.composer.system.NetworkAdmin" @@ -27,7 +28,10 @@ rule NetworkAdminSystem { resource: "org.hyperledger.composer.system.**" action: ALLOW } +/** +* end of V0.14 additions */ + /** * **/ diff --git a/Chapter10/network/test/sample.js b/Chapter10/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter10/network/test/sample.js +++ b/Chapter10/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter10/package.json b/Chapter10/package.json index 1d086ff..57535e3 100644 --- a/Chapter10/package.json +++ b/Chapter10/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter10/startup.sh b/Chapter10/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter10/startup.sh +++ b/Chapter10/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter10/z2c_login b/Chapter10/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter10/z2c_login +++ b/Chapter10/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter11/Documentation/Chinese/Z2B Chapter11.pdf b/Chapter11/Documentation/Chinese/Z2B Chapter11.pdf index e87c74e..8729c32 100644 Binary files a/Chapter11/Documentation/Chinese/Z2B Chapter11.pdf and b/Chapter11/Documentation/Chinese/Z2B Chapter11.pdf differ diff --git a/Chapter11/Documentation/Chinese/Z2B Chapter11.pptx b/Chapter11/Documentation/Chinese/Z2B Chapter11.pptx new file mode 100644 index 0000000..1d2f4c0 Binary files /dev/null and b/Chapter11/Documentation/Chinese/Z2B Chapter11.pptx differ diff --git a/Chapter11/Documentation/Espanol/Z2B Chapter11.pdf b/Chapter11/Documentation/Espanol/Z2B Chapter11.pdf index 0098e87..32a7e10 100644 Binary files a/Chapter11/Documentation/Espanol/Z2B Chapter11.pdf and b/Chapter11/Documentation/Espanol/Z2B Chapter11.pdf differ diff --git a/Chapter11/Documentation/Espanol/Z2B Chapter11.pptx b/Chapter11/Documentation/Espanol/Z2B Chapter11.pptx new file mode 100644 index 0000000..02bb38a Binary files /dev/null and b/Chapter11/Documentation/Espanol/Z2B Chapter11.pptx differ diff --git a/Chapter11/Documentation/Japanese/Z2B Chapter11.pdf b/Chapter11/Documentation/Japanese/Z2B Chapter11.pdf index 3ba27b0..d0703e5 100644 Binary files a/Chapter11/Documentation/Japanese/Z2B Chapter11.pdf and b/Chapter11/Documentation/Japanese/Z2B Chapter11.pdf differ diff --git a/Chapter11/Documentation/Japanese/Z2B Chapter11.pptx b/Chapter11/Documentation/Japanese/Z2B Chapter11.pptx new file mode 100644 index 0000000..615c452 Binary files /dev/null and b/Chapter11/Documentation/Japanese/Z2B Chapter11.pptx differ diff --git a/Chapter11/Documentation/Z2B Chapter11.pdf b/Chapter11/Documentation/Z2B Chapter11.pdf index 62029f3..434d7c8 100644 Binary files a/Chapter11/Documentation/Z2B Chapter11.pdf and b/Chapter11/Documentation/Z2B Chapter11.pdf differ diff --git a/Chapter11/Documentation/answers/CSS/pageStyles_complete.css b/Chapter11/Documentation/answers/CSS/pageStyles_complete.css index ee42c1c..bbf2c34 100755 --- a/Chapter11/Documentation/answers/CSS/pageStyles_complete.css +++ b/Chapter11/Documentation/answers/CSS/pageStyles_complete.css @@ -88,6 +88,12 @@ body {height: 100%} } } h2 {font-size: 1.5em; margin-top: .25em; margin-bottom: .25em;} +.strike { + +} +.strike::before { + +} .buyer { background-color: #CBCFD0; } .seller { background-color: rgb(173, 242, 173);} .provider { background-color: rgb(192, 221, 252);} @@ -113,7 +119,6 @@ p.message{ background-color: #DCE8CB } .halfPane{ - font-size: 1em; position: absolute; height: 40%; margin: .0625em; @@ -121,7 +126,6 @@ p.message{ overflow: hidden; } .halfPane2{ - font-size: 1em; position: absolute; height: 40%; margin: .0625em; diff --git a/Chapter11/Documentation/answers/js/z2b-events_complete.js b/Chapter11/Documentation/answers/js/z2b-events_complete.js index f0cfc7f..7b22165 100644 --- a/Chapter11/Documentation/answers/js/z2b-events_complete.js +++ b/Chapter11/Documentation/answers/js/z2b-events_complete.js @@ -14,34 +14,37 @@ // z2c-events.js +'use strict'; + /** * load the four initial user roles into a single page. */ function singleUX () { - var toLoad = 'singleUX.html' - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) - { msgPort = _port.port; - $('#body').empty(); - $('#body').append(_page); - loadBuyerUX(); - loadSellerUX(); - loadProviderUX(); - loadShipperUX(); - }); - } - else{ - $.when($.get(toLoad)).done(function(_page) + let toLoad = 'singleUX.html'; + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) { - $('#body').empty(); - $('#body').append(_page); - loadBuyerUX(); - loadSellerUX(); - loadProviderUX(); - loadShipperUX(); + msgPort = _port.port; + $('#body').empty(); + $('#body').append(_page); + loadBuyerUX(); + loadSellerUX(); + loadProviderUX(); + loadShipperUX(); }); - } + } + else{ + $.when($.get(toLoad)).done(function(_page) + { + $('#body').empty(); + $('#body').append(_page); + loadBuyerUX(); + loadSellerUX(); + loadProviderUX(); + loadShipperUX(); + }); + } } /** * load all of the members in the network for use in the different user experiences. This is a synchronous routine and is executed autormatically on web app start. @@ -49,25 +52,25 @@ function singleUX () */ function memberLoad () { - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = _buyers[0].members; - sellers = _sellers[0].members; - s_string = _getMembers(sellers); - providers = _providers[0].members - p_string = _getMembers(providers); - shippers = _shippers[0].members - sh_string = _getMembers(shippers); - }); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = _buyers[0].members; + sellers = _sellers[0].members; + s_string = _getMembers(sellers); + providers = _providers[0].members; + p_string = _getMembers(providers); + shippers = _shippers[0].members; + sh_string = _getMembers(shippers); + }); } /** * load all of the members in the network for use in the different user experiences. This routine is designed for use if the network has been newly deployed and the web app was @@ -75,28 +78,28 @@ function memberLoad () */ function deferredMemberLoad() { - var d_prompts = $.Deferred(); - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = _buyers[0].members; - sellers = _sellers[0].members; - s_string = _getMembers(sellers); - providers = _providers[0].members - p_string = _getMembers(providers); - shippers = _shippers[0].members - sh_string = _getMembers(shippers); - d_prompts.resolve(); - }).fail(d_prompts.reject); - return d_prompts.promise(); + let d_prompts = $.Deferred(); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = _buyers[0].members; + sellers = _sellers[0].members; + s_string = _getMembers(sellers); + providers = _providers[0].members; + p_string = _getMembers(providers); + shippers = _shippers[0].members; + sh_string = _getMembers(shippers); + d_prompts.resolve(); + }).fail(d_prompts.reject); + return d_prompts.promise(); } /** * return an option list for use in an HTML '; - return _str; + return _str; } \ No newline at end of file diff --git a/Chapter11/HTML/CSS/pageStyles.css b/Chapter11/HTML/CSS/pageStyles.css index 103020a..63f8aa7 100755 --- a/Chapter11/HTML/CSS/pageStyles.css +++ b/Chapter11/HTML/CSS/pageStyles.css @@ -88,6 +88,17 @@ body {height: 100%} } } h2 {font-size: 1.5em; margin-top: .25em; margin-bottom: .25em;} +.strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: rgb(173, 242, 173);} .provider { background-color: rgb(192, 221, 252);} @@ -113,10 +124,21 @@ p.message{ background-color: #DCE8CB } .halfPane{ - + font-size: 1em; + position: absolute; + height: 40%; + margin: .0625em; + width: 48%; + overflow: hidden; } .halfPane2{ - + font-size: 1em; + position: absolute; + height: 40%; + margin: .0625em; + top: 50%; + width: 48%; + overflow: hidden; } .scrollingPaneTopLeft{ diff --git a/Chapter11/HTML/admin.html b/Chapter11/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter11/HTML/admin.html +++ b/Chapter11/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
-
+ \ No newline at end of file diff --git a/Chapter11/HTML/adminHelp.html b/Chapter11/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter11/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter11/HTML/favicon.ico b/Chapter11/HTML/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter11/HTML/favicon.ico and b/Chapter11/HTML/favicon.ico differ diff --git a/Chapter11/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter11/HTML/fonts/glyphicons-halflings-regular.ttf index 1413fc6..1f85312 100644 Binary files a/Chapter11/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter11/HTML/fonts/glyphicons-halflings-regular.ttf differ diff --git a/Chapter11/HTML/icons/Search.ico b/Chapter11/HTML/icons/Search.ico index e1d39ae..fd437a0 100755 Binary files a/Chapter11/HTML/icons/Search.ico and b/Chapter11/HTML/icons/Search.ico differ diff --git a/Chapter11/HTML/js/z2b-admin.js b/Chapter11/HTML/js/z2b-admin.js index c716cb8..67f421a 100644 --- a/Chapter11/HTML/js/z2b-admin.js +++ b/Chapter11/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -130,55 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= ''} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter11/HTML/js/z2b-buyer.js b/Chapter11/HTML/js/z2b-buyer.js index 409979a..29b99c0 100644 --- a/Chapter11/HTML/js/z2b-buyer.js +++ b/Chapter11/HTML/js/z2b-buyer.js @@ -14,166 +14,173 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; +'use strict'; + +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#buyerbody").empty(); - $("#buyerbody").append(page); - // update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#buyerbody').empty(); + $('#buyerbody').append(page); + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() { _orderDiv.empty(); $("#buyer_messages").empty(); $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; }); + $('#company')[0].innerText = buyers[0].companyName; + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() { _orderDiv.empty(); $('#buyer_messages').empty(); $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the MemberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array @@ -183,113 +190,114 @@ function listOrders() */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - })(each, _orders) - } + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + })(each, _orders) + } } \ No newline at end of file diff --git a/Chapter11/HTML/js/z2b-events.js b/Chapter11/HTML/js/z2b-events.js index 79ac602..74cf7d3 100644 --- a/Chapter11/HTML/js/z2b-events.js +++ b/Chapter11/HTML/js/z2b-events.js @@ -14,45 +14,60 @@ // z2c-events.js +'use strict'; + /** * load the four initial user roles into a single page. */ function singleUX () { - var toLoad = 'singleUX.html' - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) - { - - }); - } - else{ - $.when($.get(toLoad)).done(function(_page) + let toLoad = 'singleUX.html'; + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) { + // get the msgPort + + // empty and reload the body div + + // call the load<> functions }); - } -} + } + else{ + $.when($.get(toLoad)).done(function(_page) + { + // empty and reload the body div + + // call the load<> functions + }); + } +} /** * load all of the members in the network for use in the different user experiences. This is a synchronous routine and is executed autormatically on web app start. * However, if this is a newly created network, then there are no members to retrieve and this will create four empty arrays */ -function memberLoad() +function memberLoad () { - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - - }); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = _buyers[0].members; + sellers = _sellers[0].members; + s_string = _getMembers(sellers); + providers = _providers[0].members; + p_string = _getMembers(providers); + shippers = _shippers[0].members; + sh_string = _getMembers(shippers); + }); } /** * load all of the members in the network for use in the different user experiences. This routine is designed for use if the network has been newly deployed and the web app was @@ -60,28 +75,28 @@ function memberLoad() */ function deferredMemberLoad() { - var d_prompts = $.Deferred(); - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = _buyers[0].members; - sellers = _sellers[0].members; - s_string = _getMembers(sellers); - providers = _providers[0].members - p_string = _getMembers(providers); - shippers = _shippers[0].members - sh_string = _getMembers(shippers); - d_prompts.resolve(); - }).fail(d_prompts.reject); - return d_prompts.promise(); + let d_prompts = $.Deferred(); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = _buyers[0].members; + sellers = _sellers[0].members; + s_string = _getMembers(sellers); + providers = _providers[0].members; + p_string = _getMembers(providers); + shippers = _shippers[0].members; + sh_string = _getMembers(shippers); + d_prompts.resolve(); + }).fail(d_prompts.reject); + return d_prompts.promise(); } /** * return an option list for use in an HTML '; - return _str; + return _str; } \ No newline at end of file diff --git a/Chapter11/HTML/js/z2b-financeCo.js b/Chapter11/HTML/js/z2b-financeCo.js index ea8d21e..a74a755 100644 --- a/Chapter11/HTML/js/z2b-financeCo.js +++ b/Chapter11/HTML/js/z2b-financeCo.js @@ -14,185 +14,196 @@ // z2c-financeCo.js -var financeCOorderDiv = "financeCOorderDiv"; -var orders = []; +'use strict'; + +let financeCOorderDiv = 'financeCOorderDiv'; +let orders = []; const financeCoID = 'easymoney@easymoneyinc.com'; -const financeCoName = 'The Global Financier'; /** - * load the administration User Experience + * load the finance company User Experience */ function loadFinanceCoUX () { - toLoad = "financeCo.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupFinanceCo(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'financeCo.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupFinanceCo(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupFinanceCo(page[0], port[0]);}); + } } - +/** + * @param {String} page HTML page to load + * @param {Integer} port Websocket port to use + */ function setupFinanceCo(page, port) { - $("#body").empty(); - $("#body").append(page); - updatePage("financeCo"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('finance_messages', msgPort); - var _clear = $("#financeCOclear"); - var _list = $("#financeCOorderStatus"); - var _orderDiv = $("#"+financeCOorderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listFinanceOrders()}); + $('#body').empty(); + $('#body').append(page); + updatePage( 'financeCo'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('finance_messages', msgPort); + let _clear = $('#financeCOclear'); + let _list = $('#financeCOorderStatus'); + let _orderDiv = $('#'+financeCOorderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listFinanceOrders();}); } /** - * lists all orders for the selected seller + * lists all orders for the selected financier */ function listFinanceOrders() { - var options = {}; - options.id = financeCoID; - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = financeCoID; + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#"+financeCOorderDiv).empty(); $("#"+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} - else{orders = _results.orders; formatFinanceOrders($("#"+financeCOorderDiv), orders)} - }); - }); + if (_results.orders.length < 1) {$('#'+financeCOorderDiv).empty(); $('#'+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} + else{orders = _results.orders; formatFinanceOrders($('#'+financeCOorderDiv), orders);} + }); } + /** * used by the listOrders() function - * formats the orders for a buyer. Orders to be formatted are provided in the _orders array + * formats the orders for a financier. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target * @param _target - string with div id prefaced by # * @param _orders - array with order objects */ function formatFinanceOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let p_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a financier can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - break; + _date = _arr[_idx].delivered; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - break; + _date = _arr[_idx].created; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - _action += '' - break; + _date = _arr[_idx].approved; + _action += ''; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - break; + _date = _arr[_idx].bought; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Refund.code: - _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; - break; + _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += '
'; - _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_arr[_idx].buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= formatDetail(_idx, _arr[_idx]); - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { - $("#f_order"+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#order"+_idx+"_b").on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#f_btn_"+_idx).on('click', function () + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + let _len = 'resource:org.acme.Z2BTestNetwork.Buyer#'.length; + let _buyer = _arr[_idx].buyer.substring(_len, _arr[_idx].buyer.length); + _str += '
'; + _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= formatDetail(_idx, _arr[_idx]); + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) { - var options = {}; - options.action = $("#f_action"+_idx).find(":selected").text(); - options.orderNo = $("#f_order"+_idx).text(); - options.participant = financeCoID; - console.log(options); - $("#finance_messages").prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#finance_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } + $('#f_order'+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#order'+_idx+'_b').on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#f_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#f_action'+_idx).find(':selected').text(); + options.orderNo = $('#f_order'+_idx).text(); + options.participant = financeCoID; + console.log(options); + $('#finance_messages').prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#finance_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); + } } /** * format the accordian with the details for this order */ function formatDetail(_cur, _order) { - console.log('['+_cur+'] is ',_order); - var _out = '
'; - _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; - _out += ''; - _out += ''; - _out += (_order.cancelled === "") ? '' : ''; - _out += (_order.bought === "") ? '' : ''; - _out += (_order.ordered === "") ? '' : ''; - _out += (_order.dateBackordered === "") ? '' : ''; - _out += (_order.requestShipment === "") ? '' : ''; - _out += (_order.delivering === "") ? '' : ''; - _out += (_order.delivered === "") ? '' : ''; - _out += (_order.paymentRequested === "") ? '' : ''; - _out += (_order.disputeOpened === "") ? '' : ''; - if (_order.disputeResolved === "") - { - if (_order.disputeOpened === "") - {_out += '';} + console.log('['+_cur+'] is ',_order); + let _out = '
'; + _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; + _out += '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
'; + _out += ''; + _out += (_order.cancelled === '') ? '' : ''; + _out += (_order.bought === '') ? '' : ''; + _out += (_order.ordered === '') ? '' : ''; + _out += (_order.dateBackordered === '') ? '' : ''; + _out += (_order.requestShipment === '') ? '' : ''; + _out += (_order.delivering === '') ? '' : ''; + _out += (_order.delivered === '') ? '' : ''; + _out += (_order.paymentRequested === '') ? '' : ''; + _out += (_order.disputeOpened === '') ? '' : ''; + if (_order.disputeResolved === '') + { + if (_order.disputeOpened === '') + {_out += '';} + else + {_out += '';} + } else - {_out += '';} - } - else - {_out +='';} - _out += (_order.orderRefunded === "") ? '' : ''; - _out += (_order.approved === "") ? '' : ''; - _out += (_order.paid === "") ? '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
Dispute ResolvedDispute is Unresolved
Dispute ResolvedDispute is Unresolved
Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'
Refund?(No Refund in Process)
Refund?'+_order.orderRefunded+''+_order.refund+'
Payment Approved(No Approval from Buyer)
Payment Approved'+_order.buyer+''+_order.approved+'
Paid(UnPaid)
' : 'Paid'+_order.financeCo+''+_order.paid+''; - return _out; + {_out +='Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'';} + _out += (_order.orderRefunded === '') ? 'Refund?(No Refund in Process)' : 'Refund?'+_order.orderRefunded+''+_order.refund+''; + _out += (_order.approved === '') ? 'Payment Approved(No Approval from Buyer)' : 'Payment Approved'+_order.buyer+''+_order.approved+''; + _out += (_order.paid === '') ? 'Paid(UnPaid)' : 'Paid'+_order.financeCo+''+_order.paid+''; + return _out; } diff --git a/Chapter11/HTML/js/z2b-initiate.js b/Chapter11/HTML/js/z2b-initiate.js index 290ef03..bc5076a 100644 --- a/Chapter11/HTML/js/z2b-initiate.js +++ b/Chapter11/HTML/js/z2b-initiate.js @@ -13,41 +13,44 @@ */ // z2c-initiate.js -var connectionProfileName = "z2b-test-profile"; -var networkFile = "zerotoblockchain-network.bna" -var businessNetwork = "zerotoblockchain-network"; -var buyers, sellers, providers, shippers; -var s_string, p_string, sh_string; +'use strict'; -var orderStatus = { - Created: {code: 1, text: 'Order Created'}, - Bought: {code: 2, text: 'Order Purchased'}, - Cancelled: {code: 3, text: 'Order Cancelled'}, - Ordered: {code: 4, text: 'Order Submitted to Provider'}, - ShipRequest: {code: 5, text: 'Shipping Requested'}, - Delivered: {code: 6, text: 'Order Delivered'}, - Delivering: {code: 15, text: 'Order being Delivered'}, - Backordered: {code: 7, text: 'Order Backordered'}, - Dispute: {code: 8, text: 'Order Disputed'}, - Resolve: {code: 9, text: 'Order Dispute Resolved'}, - PayRequest: {code: 10, text: 'Payment Requested'}, - Authorize: {code: 11, text: 'Payment Approved'}, - Paid: {code: 14, text: 'Payment Processed'}, - Refund: {code: 12, text: 'Order Refund Requested'}, - Refunded: {code: 13, text: 'Order Refunded'} +let connectionProfileName = 'z2b-test-profile'; +let networkFile = 'zerotoblockchain-network.bna'; +let businessNetwork = 'zerotoblockchain-network'; + +let buyers, sellers, providers, shippers; +let s_string, p_string, sh_string; + +let orderStatus = { + Created: {code: 1, text: 'Order Created'}, + Bought: {code: 2, text: 'Order Purchased'}, + Cancelled: {code: 3, text: 'Order Cancelled'}, + Ordered: {code: 4, text: 'Order Submitted to Provider'}, + ShipRequest: {code: 5, text: 'Shipping Requested'}, + Delivered: {code: 6, text: 'Order Delivered'}, + Delivering: {code: 15, text: 'Order being Delivered'}, + Backordered: {code: 7, text: 'Order Backordered'}, + Dispute: {code: 8, text: 'Order Disputed'}, + Resolve: {code: 9, text: 'Order Dispute Resolved'}, + PayRequest: {code: 10, text: 'Payment Requested'}, + Authorize: {code: 11, text: 'Payment Approved'}, + Paid: {code: 14, text: 'Payment Processed'}, + Refund: {code: 12, text: 'Order Refund Requested'}, + Refunded: {code: 13, text: 'Order Refunded'} }; /** * standard home page initialization routine * Refer to this by {@link initPage()}. */ - function initPage () +function initPage () { - // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English - goMultiLingual("US_English", "index"); - // singleUX loads the members already present in the network - memberLoad(); - // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring - getChainEvents(); + // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English + goMultiLingual('US_English', 'index'); + // singleUX loads the members already present in the network + memberLoad(); + // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring + getChainEvents(); } diff --git a/Chapter11/HTML/js/z2b-provider.js b/Chapter11/HTML/js/z2b-provider.js index b1ef840..68a670c 100644 --- a/Chapter11/HTML/js/z2b-provider.js +++ b/Chapter11/HTML/js/z2b-provider.js @@ -14,158 +14,171 @@ // z2c-provider.js -var providerOrderDiv = "providerOrderDiv"; +'use strict'; + +let providerOrderDiv = 'providerOrderDiv'; /** - * load the administration User Experience + * load the Provider User Experience */ function loadProviderUX () { - toLoad = "provider.html"; + let toLoad = 'provider.html'; getPort(); - if (buyers.length === 0) + if (buyers.length === 0) { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupProvider(page[0], port[0]);}); } else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupProvider(page[0], port[0]);}); + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupProvider(page[0], port[0]);}); } - } - +} + +/** + * load the Provider User Experience + * @param {String} page - the name of the page to load + * @param {Integer} port - the port number to use + */ function setupProvider(page, port) { - $("#providerbody").empty(); - $("#providerbody").append(page); - updatePage("provider"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('provider_messages', msgPort); - var _clear = $("#provider_clear"); - var _list = $("#providerOrderStatus"); - var _orderDiv = $("#"+providerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listProviderOrders()}); - $("#provider").empty(); - $("#provider").append(p_string); - $("#providerCompany").empty(); - $("#providerCompany").append(providers[0].companyName); - $("#provider").on('change', function() { - $("#providerCompany").empty(); _orderDiv.empty(); $("#provider_messages").empty(); - $("#providerCompany").append(findMember($("#provider").find(":selected").val(),providers).companyName); - }); + $('#providerbody').empty(); + $('#providerbody').append(page); + updatePage('provider'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('provider_messages', msgPort); + let _clear = $('#provider_clear'); + let _list = $('#providerOrderStatus'); + let _orderDiv = $('#'+providerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listProviderOrders();}); + $('#provider').empty(); + $('#provider').append(p_string); + $('#providerCompany').empty(); + $('#providerCompany').append(providers[0].companyName); + $('#provider').on('change', function() { + $('#providerCompany').empty(); _orderDiv.empty(); $('#provider_messages').empty(); + $('#providerCompany').append(findMember($('#provider').find(':selected').val(),providers).companyName); + }); } /** - * lists all orders for the selected seller + * lists all orders for the selected Provider */ function listProviderOrders() { - var options = {}; - options.id = $("#provider").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#provider').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#providerOrderDiv").empty(); $("#providerOrderDiv").append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} - else{formatProviderOrders($("#providerOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#providerOrderDiv').empty(); $('#providerOrderDiv').append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} + else{formatProviderOrders($('#providerOrderDiv'), _results.orders);} + }); } + /** * used by the listOrders() function - * formats the orders for a buyer. Orders to be formatted are provided in the _orders array + * formats the orders for a Provider. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target * @param _target - string with div id prefaced by # * @param _orders - array with order objects */ function formatProviderOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let b_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + b_string = ''; + // + // each order can have different states and the action that a Provider can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += ''; - _action += ''; - b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; - break; + _date = _arr[_idx].ordered; + _action += ''; + _action += ''; + b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += ''; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= ''; + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#p_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#p_action'+_idx).find(':selected').text(); + options.orderNo = $('#p_order'+_idx).text(); + options.participant = $('#provider').val(); + options.shipper = $('#shippers'+_idx).find(':selected').val(); + if ((options.action == 'Resolve') || (options.action === 'Refund') || (options.action === 'BackOrder')) {options.reason = $('#p_reason'+_idx).val();} + console.log(options); + $('#provider_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#provider_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#p_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#p_action"+_idx).find(":selected").text(); - options.orderNo = $("#p_order"+_idx).text(); - options.participant = $("#provider").val(); - options.shipper = $("#shippers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund') || (options.action == 'BackOrder')) {options.reason = $("#p_reason"+_idx).val();} - console.log(options); - $("#provider_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#provider_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter11/HTML/js/z2b-seller.js b/Chapter11/HTML/js/z2b-seller.js index b5aeb2d..410c92d 100644 --- a/Chapter11/HTML/js/z2b-seller.js +++ b/Chapter11/HTML/js/z2b-seller.js @@ -13,152 +13,171 @@ */ // z2c-seller.js -var sellerOrderDiv = "sellerOrderDiv"; + +'use strict'; +let sellerOrderDiv = 'sellerOrderDiv'; /** - * load the administration User Experience + * load the administration Seller Experience */ function loadSellerUX () { - toLoad = "seller.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupSeller(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'seller.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupSeller(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupSeller(page[0], port[0]);}); + } } +/** + * load the administration User Experience + * @param {String} page - page to load + * @param {Integer} port - web socket port to use + */ function setupSeller(page, port) { - $("#sellerbody").empty(); - $("#sellerbody").append(page); - updatePage("seller"); - msgPort = port.port; - wsDisplay('seller_messages', msgPort); - var _clear = $("#seller_clear"); - var _list = $("#sellerOrderStatus"); - var _orderDiv = $("#"+sellerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listSellerOrders()}); - $("#seller").empty(); - $("#seller").append(s_string); - $("#sellerCompany").empty(); - $("#sellerCompany").append(sellers[0].companyName); - $("#seller").on('change', function() { - $("#sellerCompany").empty(); _orderDiv.empty(); $("#seller_messages").empty(); - $("#sellerCompany").append(findMember($("#seller").find(":selected").val(),sellers).companyName); - }); + $('#sellerbody').empty(); + $('#sellerbody').append(page); + updatePage('seller'); + msgPort = port.port; + wsDisplay('seller_messages', msgPort); + let _clear = $('#seller_clear'); + let _list = $('#sellerOrderStatus'); + let _orderDiv = $('#'+sellerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + // + // this section changes from the previous chapter, buyer changing to seller + // + _list.on('click', function(){listSellerOrders();}); + $('#seller').empty(); + $('#seller').append(s_string); + $('#sellerCompany').empty(); + $('#sellerCompany').append(sellers[0].companyName); + $('#seller').on('change', function() { + $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty(); + $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName); + }); } /** * lists all orders for the selected seller */ function listSellerOrders() { - var options = {}; - options.id = $("#seller").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + // + // seller instead of buyer + // + options.id= $('#seller').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} - else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)} - }); - }); + { + if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} + else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);} + }); } /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatSellerOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += ''; - break; + _date = _arr[_idx].bought; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - var _string = '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + let _string = '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - - _target.append(_str); - for (let each in _orders) + + _target.append(_str); + for (let each in _orders) {(function(_idx, _arr) - { $("#s_btn_"+_idx).on('click', function () + { $('#s_btn_'+_idx).on('click', function () { - var options = {}; - options.action = $("#s_action"+_idx).find(":selected").text(); - options.orderNo = $("#s_order"+_idx).text(); - options.participant = $("#seller").val(); - options.provider = $("#providers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#s_reason"+_idx).val();} - $("#seller_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + let options = {}; + options.action = $('#s_action'+_idx).find(':selected').text(); + options.orderNo = $('#s_order'+_idx).text(); + options.participant = $('#seller').val(); + options.provider = $('#providers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#s_reason'+_idx).val();} + $('#seller_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#seller_messages").prepend(formatMessage(_results.result)); }); + { $('#seller_messages').prepend(formatMessage(_results.result)); }); }); - })(each, _orders) - } + })(each, _orders); + } } \ No newline at end of file diff --git a/Chapter11/HTML/js/z2b-shipper.js b/Chapter11/HTML/js/z2b-shipper.js index 1561ae0..04c13a6 100644 --- a/Chapter11/HTML/js/z2b-shipper.js +++ b/Chapter11/HTML/js/z2b-shipper.js @@ -14,154 +14,165 @@ // z2c-shipper.js -var shipperOrderDiv = "shipperOrderDiv"; +'use strict'; + +let shipperOrderDiv = 'shipperOrderDiv'; /** - * load the administration User Experience + * load the shipper User Experience */ function loadShipperUX () { - toLoad = "shipper.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupShipper(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'shipper.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupShipper(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupShipper(page[0], port[0]);}); + } } - +/** + * + * @param {String} page - the page to load + * @param {Integer} port - the web socket to use + */ function setupShipper(page, port) { - $("#shipperbody").empty(); - $("#shipperbody").append(page); - updatePage("shipper"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('shipper_messages', msgPort); - var _clear = $("#shipper_clear"); - var _list = $("#shipperOrderStatus"); - var _orderDiv = $("#"+shipperOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listShipperOrders()}); - $("#shipper").empty(); - $("#shipper").append(sh_string); - $("#shipperCompany").empty(); - $("#shipperCompany").append(providers[0].companyName); - $("#shipper").on('change', function() { - $("#shipperCompany").empty(); _orderDiv.empty(); $("#shipper_messages").empty(); - $("#shipperCompany").append(findMember($("#shipper").find(":selected").val(),shippers).companyName); - }); + $('#shipperbody').empty(); + $('#shipperbody').append(page); + updatePage('shipper'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('shipper_messages', msgPort); + let _clear = $('#shipper_clear'); + let _list = $('#shipperOrderStatus'); + let _orderDiv = $('#'+shipperOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listShipperOrders();}); + $('#shipper').empty(); + $('#shipper').append(sh_string); + $('#shipperCompany').empty(); + $('#shipperCompany').append(providers[0].companyName); + $('#shipper').on('change', function() { + $('#shipperCompany').empty(); _orderDiv.empty(); $('#shipper_messages').empty(); + $('#shipperCompany').append(findMember($('#shipper').find(':selected').val(),shippers).companyName); + }); } /** - * lists all orders for the selected seller + * lists all orders for the selected shipper */ function listShipperOrders() { - var options = {}; - options.id = $("#shipper").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#shipper').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#shipperOrderDiv").empty(); $("#shipperOrderDiv").append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} - else{formatShipperOrders($("#shipperOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#shipperOrderDiv').empty(); $('#shipperOrderDiv').append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} + else{formatShipperOrders($('#shipperOrderDiv'), _results.orders)} + }); } /** * used by the listOrders() function - * formats the orders for a buyer. Orders to be formatted are provided in the _orders array + * formats the orders for a shipper. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target * @param _target - string with div id prefaced by # * @param _orders - array with order objects */ function formatShipperOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; var _statusText; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + _statusText = ''; + // + // each order can have different states and the action that a shipper can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].requestShipment; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivering; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivered; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - console.log('OrderStatus not processed for: '+_arr[_idx].status); - break; - } - _button = '' - _action += ""; - console.log("shipper _action: "+_action); - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + console.log('OrderStatus not processed for: '+_arr[_idx].status); + break; + } + let _button = ''; + _action += ''; + console.log('shipper _action: '+_action); + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + console.log(_str); + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#sh_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#sh_action'+_idx).find(':selected').text(); + options.orderNo = $('#sh_order'+_idx).text(); + options.participant = $('#shipper').val(); + options.delivery = $('#delivery'+_idx).val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#sh_reason'+_idx).val();} + console.log(options); + $('#shipper_messages').prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#shipper_messages').prepend(formatMessage(_results.result)); + }); + }); + })(each, _orders); } - console.log(_str); - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#sh_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#sh_action"+_idx).find(":selected").text(); - options.orderNo = $("#sh_order"+_idx).text(); - options.participant = $("#shipper").val(); - options.delivery = $("#delivery"+_idx).val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#sh_reason"+_idx).val();} - console.log(options); - $("#shipper_messages").prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#shipper_messages").prepend(formatMessage(_results.result)); - }); - }); - })(each, _orders) - } } \ No newline at end of file diff --git a/Chapter11/HTML/removeMember.html b/Chapter11/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter11/HTML/removeMember.html +++ b/Chapter11/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
diff --git a/Chapter11/README.pdf b/Chapter11/README.pdf index fafcfae..4849def 100644 Binary files a/Chapter11/README.pdf and b/Chapter11/README.pdf differ diff --git a/Chapter11/buildAndDeploy b/Chapter11/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter11/buildAndDeploy +++ b/Chapter11/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter11/controller/env.json b/Chapter11/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter11/controller/env.json +++ b/Chapter11/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter11/controller/restapi/features/composer/autoLoad.js b/Chapter11/controller/restapi/features/composer/autoLoad.js index 1f5214f..ce3d81b 100644 --- a/Chapter11/controller/restapi/features/composer/autoLoad.js +++ b/Chapter11/controller/restapi/features/composer/autoLoad.js @@ -14,62 +14,57 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -84,131 +79,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -220,8 +239,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter11/controller/restapi/features/composer/hlcAdmin.js b/Chapter11/controller/restapi/features/composer/hlcAdmin.js index 27b12a3..8e9e8b9 100644 --- a/Chapter11/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter11/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter11/controller/restapi/features/composer/hlcClient.js b/Chapter11/controller/restapi/features/composer/hlcClient.js index 401bf01..bc5bfb6 100644 --- a/Chapter11/controller/restapi/features/composer/hlcClient.js +++ b/Chapter11/controller/restapi/features/composer/hlcClient.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const config = require('../../../env.json'); +// const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; /** @@ -30,53 +29,58 @@ const financeCoID = 'easymoney@easymoneyinc.com'; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -84,24 +88,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -111,155 +115,156 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - updateOrder = factory.newTransaction(NS, 'Pay'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + console.log('Pay entered'); + updateOrder = factory.newTransaction(NS, 'Pay'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + console.log('Update Delivery Status'); + updateOrder = factory.newTransaction(NS, 'Delivering'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + updateOrder.deliveryStatus = req.body.delivery; + break; + case 'Delivered': + console.log('Delivered entered'); + updateOrder = factory.newTransaction(NS, 'Deliver'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -268,85 +273,87 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; diff --git a/Chapter11/controller/restapi/features/text/ch/prompts.json b/Chapter11/controller/restapi/features/text/ch/prompts.json index 7cd00f8..b3b965a 100644 --- a/Chapter11/controller/restapi/features/text/ch/prompts.json +++ b/Chapter11/controller/restapi/features/text/ch/prompts.json @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", diff --git a/Chapter11/controller/restapi/features/text/en-UK/prompts.json b/Chapter11/controller/restapi/features/text/en-UK/prompts.json index 44af131..94a6abe 100644 --- a/Chapter11/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter11/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "US English", - "title": "Z2B Chapter 11", - "header": "Chapter 11: Integrating the User Experiences", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter 11", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 11. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 11: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 11, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 11, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 11, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 11", + "header":"Chapter 11: Integrating the User Views", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter11/controller/restapi/features/text/en-US/prompts.json b/Chapter11/controller/restapi/features/text/en-US/prompts.json index 44af131..5e65290 100644 --- a/Chapter11/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter11/controller/restapi/features/text/en-US/prompts.json @@ -53,7 +53,10 @@ "rm_am_api": "Add Member", "rm_am_param": "Co Name, id, Type", "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", "bc": "BlockChain", "bc_api": "API", "bc_param": "Parameters", @@ -96,8 +99,8 @@ "cd_financeco": "FinanceCo", "cd_cn": "Company Name", "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" + "cancel": "Cancel", + "submit": "Submit" }, "createOrder": { "title": "Create New Order", diff --git a/Chapter11/controller/restapi/features/text/es-LA/prompts.json b/Chapter11/controller/restapi/features/text/es-LA/prompts.json index d01722b..abedc73 100644 --- a/Chapter11/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter11/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 11", - "header":"Capítulo 11: Integrando los puntos de vista de los usuarios", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 11", + "header":"Capítulo 11: Integrando los puntos de vista de los usuarios", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter11/controller/restapi/features/text/fr/prompts.json b/Chapter11/controller/restapi/features/text/fr/prompts.json index 13da100..4d0c51a 100644 --- a/Chapter11/controller/restapi/features/text/fr/prompts.json +++ b/Chapter11/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 11", - "header":"Chapitre 11 : Intégrer les vues utilisateur", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 05", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { - "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", - "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { - "title":"Zero to Blockchain Chapitre 10: Le financier mondial", - "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { - "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", - "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { - "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", - "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { - "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", - "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer(0) demander le numero de commande:(1)", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 11", + "header":"Chapitre 11 : Intégrer les vues utilisateur", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { + "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", + "newOrder":"Créér une nouvelle commande", + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { + "title":"Zero to Blockchain Chapitre 10: Le financier mondial", + "financeCOclear":"Effacer le contenu de la fenetre", + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { + "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", + "provider_clear":"Effacer le contenu de la fenetre", + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { + "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", + "seller_clear":"Effacer le contenu de la fenetre", + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { + "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", + "shipper_clear":"Effacer le contenu de la fenetre", + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter11/controller/restapi/features/text/jp/prompts.json b/Chapter11/controller/restapi/features/text/jp/prompts.json index 1de1468..e3e5fb0 100644 --- a/Chapter11/controller/restapi/features/text/jp/prompts.json +++ b/Chapter11/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 11章", - "header":"弟 11章: ユーザービューの統合", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟05章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟07章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 11章", + "header":"弟 11章: ユーザービューの統合", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter11/controller/restapi/features/text/languages.json b/Chapter11/controller/restapi/features/text/languages.json index 91b0348..8ee6b21 100644 --- a/Chapter11/controller/restapi/features/text/languages.json +++ b/Chapter11/controller/restapi/features/text/languages.json @@ -6,6 +6,6 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, - "Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} + "Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } \ No newline at end of file diff --git a/Chapter11/controller/restapi/features/text/pt/prompts.json b/Chapter11/controller/restapi/features/text/pt/prompts.json index 4a3c1db..8399a9d 100644 --- a/Chapter11/controller/restapi/features/text/pt/prompts.json +++ b/Chapter11/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 11", + "header":"Capítulo 11: Integrando as Visualizações do Usuário", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter11/controller/restapi/router.js b/Chapter11/controller/restapi/router.js index 931a9e2..6fa15bd 100644 --- a/Chapter11/controller/restapi/router.js +++ b/Chapter11/controller/restapi/router.js @@ -12,27 +12,50 @@ * limitations under the License. */ +'use strict'; -var express = require('express'); -var router = express.Router(); -var format = require('date-format'); +let express = require('express'); +let router = express.Router(); +let format = require('date-format'); -var multi_lingual = require('./features/multi_lingual'); -var resources = require('./features/resources'); -var getCreds = require('./features/getCredentials'); -var hlcAdmin = require('./features/composer/hlcAdmin'); -var hlcClient = require('./features/composer/hlcClient'); -var hlcFabric = require('./features/composer/queryBlockChain'); -var setup = require('./features/composer/autoLoad'); +let multi_lingual = require('./features/multi_lingual'); +let resources = require('./features/resources'); +let getCreds = require('./features/getCredentials'); +let hlcAdmin = require('./features/composer/hlcAdmin'); +let hlcClient = require('./features/composer/hlcClient'); +let setup = require('./features/composer/autoLoad'); +let hlcFabric = require('./features/composer/queryBlockChain'); +router.post('/setup/autoLoad*', setup.autoLoad); +router.get('/setup/getPort*', setup.getPort); + +router.get('/fabric/getChainInfo', hlcFabric.getChainInfo); +router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); +router.get('/fabric/getHistory', hlcAdmin.getHistory); module.exports = router; -var count = 0; +let count = 0; +/** + * This is a request tracking function which logs to the terminal window each request coming in to the web serve and + * increments a counter to allow the requests to be sequenced. + * @param {express.req} req - the inbound request object from the client + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * + * @function + */ router.use(function(req, res, next) { - count++; - console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); - next(); // make sure we go to the next routes and don't stop here + count++; + console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); + next(); // make sure we go to the next routes and don't stop here }); +// the following get and post statements tell nodeJS what to do when a request comes in +// The request is the single quoted phrase following the get( or post( statement. +// the text at the end identifies which function in which require(d) module to implement +// These are searched in order by get/post request. +// The asterisk (*) means 'ignore anything following this point' +// which means we have to be careful about ordering these statements. +// router.get('/api/getSupportedLanguages*',multi_lingual.languages); router.get('/api/getTextLocations*',multi_lingual.locations); router.post('/api/selectedPrompts*',multi_lingual.prompts); @@ -47,7 +70,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -64,15 +86,12 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); -router.post('/setup/autoLoad*', setup.autoLoad); -router.get('/setup/getPort*', setup.getPort); - +// router requests specific to the Buyer router.get('/composer/client/getItemTable*', hlcClient.getItemTable); router.post('/composer/client/getMyOrders*', hlcClient.getMyOrders); router.post('/composer/client/addOrder*', hlcClient.addOrder); -router.post('/composer/client/orderAction*', hlcClient.orderAction); - -router.get('/fabric/getChainInfo', hlcFabric.getChainInfo); -router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); -router.get('/fabric/getHistory', hlcAdmin.getHistory); +router.post('/composer/client/orderAction*', hlcClient.orderAction); \ No newline at end of file diff --git a/Chapter11/createArchive.sh b/Chapter11/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter11/createArchive.sh +++ b/Chapter11/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter11/deployNetwork.sh b/Chapter11/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter11/deployNetwork.sh +++ b/Chapter11/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter11/favicon.ico b/Chapter11/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter11/favicon.ico and b/Chapter11/favicon.ico differ diff --git a/Chapter11/network/dist/networkadmin.card b/Chapter11/network/dist/networkadmin.card new file mode 100644 index 0000000..d20bf1b Binary files /dev/null and b/Chapter11/network/dist/networkadmin.card differ diff --git a/Chapter11/network/package.json b/Chapter11/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter11/network/package.json +++ b/Chapter11/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter11/network/test/sample.js b/Chapter11/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter11/network/test/sample.js +++ b/Chapter11/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter11/package.json b/Chapter11/package.json index 1d086ff..57535e3 100644 --- a/Chapter11/package.json +++ b/Chapter11/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter11/startup.sh b/Chapter11/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter11/startup.sh +++ b/Chapter11/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter11/z2c_login b/Chapter11/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter11/z2c_login +++ b/Chapter11/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/Chapter12/Documentation/Z2B Chapter12.pdf b/Chapter12/Documentation/Z2B Chapter12.pdf index a27433a..218e025 100644 Binary files a/Chapter12/Documentation/Z2B Chapter12.pdf and b/Chapter12/Documentation/Z2B Chapter12.pdf differ diff --git a/Chapter12/Documentation/answers/CSS/pageStyles_complete.css b/Chapter12/Documentation/answers/CSS/pageStyles_complete.css index 3bc804f..69f4ecc 100755 --- a/Chapter12/Documentation/answers/CSS/pageStyles_complete.css +++ b/Chapter12/Documentation/answers/CSS/pageStyles_complete.css @@ -114,6 +114,17 @@ body {height: 100%} .n_count.on { font-size: .5em; font-weight: bold; visibility: visible;} .n_count.off { font-size: .5em; font-weight: bold; visibility: hidden;} h2 {font-size: 1.5em; margin-top: .25em; margin-bottom: .25em;} + .strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: rgb(173, 242, 173);} .provider { background-color: rgb(192, 221, 252);} diff --git a/Chapter12/Documentation/answers/composer/hlcClient_complete.js b/Chapter12/Documentation/answers/composer/hlcClient_complete.js index dcce523..b1c4e1d 100644 --- a/Chapter12/Documentation/answers/composer/hlcClient_complete.js +++ b/Chapter12/Documentation/answers/composer/hlcClient_complete.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; let bRegistered = false; @@ -31,54 +30,58 @@ let bRegistered = false; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); - businessNetworkConnection.setMaxListeners(50); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -86,24 +89,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -113,156 +116,156 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - businessNetworkConnection.setMaxListeners(50); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - updateOrder = factory.newTransaction(NS, 'Pay'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + console.log('Pay entered'); + updateOrder = factory.newTransaction(NS, 'Pay'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + console.log('Update Delivery Status'); + updateOrder = factory.newTransaction(NS, 'Delivering'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + updateOrder.deliveryStatus = req.body.delivery; + break; + case 'Delivered': + console.log('Delivered entered'); + updateOrder = factory.newTransaction(NS, 'Deliver'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -271,99 +274,101 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - businessNetworkConnection.setMaxListeners(50); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; /** * Register for all of the available Z2BEvents * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {Object} - returns are via res.send */ exports.init_z2bEvents = function (req, res, next) { - var method = 'init_z2bEvents'; + let method = 'init_z2bEvents'; if (bRegistered) {res.send('Already Registered');} else{ bRegistered = true; @@ -371,80 +376,98 @@ exports.init_z2bEvents = function (req, res, next) let businessNetworkConnection; businessNetworkConnection = new BusinessNetworkConnection(); businessNetworkConnection.setMaxListeners(50); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // + // v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { + // using the businessNetworkConnection, start monitoring for events. + // when an event is provided, call the _monitor function, passing in the al_connection, f_connection and event information businessNetworkConnection.on('event', (event) => {_monitor(svc.al_connection, svc.f_connection, event); }); res.send('event registration complete'); }).catch((error) => { - console.log(method+' business network connection failed'+error.message); + // if an error is encountered, log the error and send it back to the requestor + console.log(method+' business network connection failed'+error.message); res.send(method+' business network connection failed'+error.message); }); } -} +}; /** * _monitor - * @param {org.acme.z2bNetwork.Event} _event - the event just emitted - * + * @param {WebSocket} _conn - web socket to use for member event posting + * @param {WebSocket} _f_conn - web sockect to use for FinanceCo event posting + * @param {Event} _event - the event just emitted + * */ function _monitor(_conn, _f_conn, _event) { - var method = '_monitor'; + let method = '_monitor'; console.log(method+ ' _event received: '+_event.$type+' for Order: '+_event.orderID); - var event = {}; + // create an event object and give it the event type, the orderID, the buyer id and the eventID + // send that event back to the requestor + let event = {}; event.type = _event.$type; event.orderID = _event.orderID; event.ID = _event.buyerID; _conn.sendUTF(JSON.stringify(event)); - + + // using switch/case logic, send events back to each participant who should be notified. + // for example, when a seller requests payment, they should be notified when the transaction has completed + // and the financeCo should be notified at the same time. + // so you would use the _conn connection to notify the seller and the + // _f_conn connection to notify the financeCo + switch (_event.$type) { - case 'Created': + case 'Created': break; - case 'Bought': - case 'PaymentRequested': - event.ID = _event.sellerID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.financeCoID; - _f_conn.sendUTF(JSON.stringify(event)); + case 'Bought': + case 'PaymentRequested': + event.ID = _event.sellerID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.financeCoID; + _f_conn.sendUTF(JSON.stringify(event)); break; - case 'Ordered': - case 'Cancelled': - case 'Backordered': - event.ID = _event.sellerID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.providerID; - _conn.sendUTF(JSON.stringify(event)); + case 'Ordered': + case 'Cancelled': + case 'Backordered': + event.ID = _event.sellerID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.providerID; + _conn.sendUTF(JSON.stringify(event)); break; - case 'ShipRequest': - case 'DeliveryStarted': - case 'DeliveryCompleted': - event.ID = _event.sellerID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.providerID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.shipperID; - _conn.sendUTF(JSON.stringify(event)); + case 'ShipRequest': + case 'DeliveryStarted': + case 'DeliveryCompleted': + event.ID = _event.sellerID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.providerID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.shipperID; + _conn.sendUTF(JSON.stringify(event)); break; - case 'DisputeOpened': - case 'Resolved': - case 'Refunded': - case 'Paid': - event.ID = _event.sellerID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.providerID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.shipperID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.financeCoID; - _f_conn.sendUTF(JSON.stringify(event)); + case 'DisputeOpened': + case 'Resolved': + case 'Refunded': + case 'Paid': + event.ID = _event.sellerID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.providerID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.shipperID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.financeCoID; + _f_conn.sendUTF(JSON.stringify(event)); break; - case 'PaymentAuthorized': - event.ID = _event.sellerID; - _conn.sendUTF(JSON.stringify(event)); - event.ID = _event.financeCoID; - _f_conn.sendUTF(JSON.stringify(event)); + case 'PaymentAuthorized': + event.ID = _event.sellerID; + _conn.sendUTF(JSON.stringify(event)); + event.ID = _event.financeCoID; + _f_conn.sendUTF(JSON.stringify(event)); break; - default: + default: break; } diff --git a/Chapter12/Documentation/answers/js/z2b-buyer_complete.js b/Chapter12/Documentation/answers/js/z2b-buyer_complete.js index 220fe89..49d7795 100644 --- a/Chapter12/Documentation/answers/js/z2b-buyer_complete.js +++ b/Chapter12/Documentation/answers/js/z2b-buyer_complete.js @@ -14,302 +14,321 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; -var b_notify = '#buyer_notify'; -var b_count = '#buyer_count'; -var b_id = ''; -var b_alerts; +'use strict'; +let b_notify = '#buyer_notify'; +let b_count = '#buyer_count'; +let b_id = ''; +let b_alerts; +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#buyerbody").empty(); - $("#buyerbody").append(page); - b_alerts = []; - if (b_alerts.length == 0) - {$(b_notify).removeClass('on'); $(b_notify).addClass('off'); } - else {$(b_notify).removeClass('off'); $(b_notify).addClass('on'); } - // update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#buyerbody').empty(); + $('#buyerbody').append(page); + // empty the buyer alerts array + b_alerts = []; + // if there are no alerts, then remove the 'on' class and add the 'off' class + if (b_alerts.length === 0) + {$(b_notify).removeClass('on'); $(b_notify).addClass('off'); } + else {$(b_notify).removeClass('off'); $(b_notify).addClass('on'); } + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - b_id = buyers[0].id; - z2bSubscribe('Buyer', b_id); - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() - { _orderDiv.empty(); $("#buyer_messages").empty(); - $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; - z2bUnSubscribe(b_id); - b_id = findMember($("#buyer").find(":selected").text(),buyers).id; - z2bSubscribe('Buyer', b_id); + $('#company')[0].innerText = buyers[0].companyName; + // save the current buyer id as b_id + b_id = buyers[0].id; + // subscribe to events + z2bSubscribe('Buyer', b_id); + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() + { _orderDiv.empty(); $('#buyer_messages').empty(); + $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; + // unsubscribe the current buyer + z2bUnSubscribe(b_id); + // get the new buyer id + b_id = findMember($('#buyer').find(':selected').text(),buyers).id; + // subscribe the new buyer + z2bSubscribe('Buyer', b_id); }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the MemberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - if (notifyMe(b_alerts, _arr[_idx].id)) {$("#b_status"+_idx).addClass('highlight'); } - })(each, _orders) - } - b_alerts = new Array(); - toggleAlert($('#buyer_notify'), b_alerts, b_alerts.length); -} + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) + {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + // use the notifyMe function to determine if this order is in the alert array. + // if it is, the highlight the $('#b_status'+_idx) html element by adding the 'highlight' class + if (notifyMe(b_alerts, _arr[_idx].id)) {$('#b_status'+_idx).addClass('highlight'); } + })(each, _orders); + } + // reset the b_alerts array to a new array + b_alerts = new Array(); + // call the toggleAlerts function to reset the alert icon + toggleAlert($('#buyer_notify'), b_alerts, b_alerts.length); +} \ No newline at end of file diff --git a/Chapter12/Documentation/answers/js/z2b-events_complete.js b/Chapter12/Documentation/answers/js/z2b-events_complete.js index be2c0d1..44c5ef5 100644 --- a/Chapter12/Documentation/answers/js/z2b-events_complete.js +++ b/Chapter12/Documentation/answers/js/z2b-events_complete.js @@ -13,41 +13,44 @@ */ // z2c-events.js -var alertPort = null; -var financeAlertPort = null; + +'use strict'; + +let alertPort = null; +let financeAlertPort = null; /** * load the four initial user roles into a single page. */ function singleUX () { - var toLoad = 'singleUX.html' - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) - { msgPort = _port.port; - $('#body').empty(); - $('#body').append(_page); - loadBuyerUX(); - loadSellerUX(); - loadProviderUX(); - loadShipperUX(); - // Initialize Registration for all Z2B Business Events - goEventInitialize(); -}); - } - else{ - $.when($.get(toLoad)).done(function(_page) - { - $('#body').empty(); - $('#body').append(_page); - loadBuyerUX(); - loadSellerUX(); - loadProviderUX(); - loadShipperUX(); - // Initialize Registration for all Z2B Business Events - goEventInitialize(); + let toLoad = 'singleUX.html'; + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) + { msgPort = _port.port; + $('#body').empty(); + $('#body').append(_page); + loadBuyerUX(); + loadSellerUX(); + loadProviderUX(); + loadShipperUX(); + // Initialize Registration for all Z2B Business Events + goEventInitialize(); }); - } + } + else{ + $.when($.get(toLoad)).done(function(_page) + { + $('#body').empty(); + $('#body').append(_page); + loadBuyerUX(); + loadSellerUX(); + loadProviderUX(); + loadShipperUX(); + // Initialize Registration for all Z2B Business Events + goEventInitialize(); + }); + } } /** * load all of the members in the network for use in the different user experiences. This is a synchronous routine and is executed autormatically on web app start. @@ -55,35 +58,36 @@ function singleUX () */ function memberLoad () { - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = dropDummy(_buyers[0].members); - sellers = dropDummy(_sellers[0].members); - providers = dropDummy(_providers[0].members); - shippers = dropDummy(_shippers[0].members); - s_string = _getMembers(sellers); - p_string = _getMembers(providers); - sh_string = _getMembers(shippers); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = dropDummy(_buyers[0].members); + sellers = dropDummy(_sellers[0].members); + providers = dropDummy(_providers[0].members); + shippers = dropDummy(_shippers[0].members); + s_string = _getMembers(sellers); + p_string = _getMembers(providers); + sh_string = _getMembers(shippers); - }); + }); } /** * dropDummy() removes 'noop@dummy' from memberlist + * @param {String} _in - member id to ignore */ function dropDummy(_in) { - var _a = new Array() - for (each in _in){(function(_idx, _arr){console.log('_arr['+_idx+'].id is: '+_arr[_idx].id); if (_arr[_idx].id !== 'noop@dummy')_a.push(_arr[_idx]);})(each, _in)} - return _a; + let _a = new Array() + for (let each in _in){(function(_idx, _arr){console.log('_arr['+_idx+'].id is: '+_arr[_idx].id); if (_arr[_idx].id !== 'noop@dummy')_a.push(_arr[_idx]);})(each, _in);} + return _a; } /** * load all of the members in the network for use in the different user experiences. This routine is designed for use if the network has been newly deployed and the web app was @@ -91,47 +95,48 @@ function dropDummy(_in) */ function deferredMemberLoad() { - var d_prompts = $.Deferred(); - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = dropDummy(_buyers[0].members); - sellers = dropDummy(_sellers[0].members); - providers = dropDummy(_providers[0].members); - shippers = dropDummy(_shippers[0].members); - s_string = _getMembers(sellers); - p_string = _getMembers(providers); - sh_string = _getMembers(shippers); - d_prompts.resolve(); - }).fail(d_prompts.reject); - return d_prompts.promise(); + let d_prompts = $.Deferred(); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = dropDummy(_buyers[0].members); + sellers = dropDummy(_sellers[0].members); + providers = dropDummy(_providers[0].members); + shippers = dropDummy(_shippers[0].members); + s_string = _getMembers(sellers); + p_string = _getMembers(providers); + sh_string = _getMembers(shippers); + d_prompts.resolve(); + }).fail(d_prompts.reject); + return d_prompts.promise(); } /** * return an option list for use in an HTML '; - return _str; + return _str; } /** * set up the server to listen for all events */ function goEventInitialize() { - $.when($.get('/composer/client/initEventRegistry')).done(function(_res){console.log(_res);}) + $.when($.get('/composer/client/initEventRegistry')).done(function(_res){console.log(_res);}) } /** @@ -139,129 +144,137 @@ function goEventInitialize() */ function getAlertPort () { - if (alertPort == null) - { - $.when($.get('/setup/getAlertPort')).done(function (port) + if (alertPort === null) { - console.log('alert port is: '+port.port); alertPort = port.port; - var wsSocket = new WebSocket('ws://localhost:'+alertPort); - wsSocket.onopen = function () {wsSocket.send('connected to alerts');}; - wsSocket.onmessage = function (message) { - console.log(message.data); - var event = JSON.parse(message.data); - addNotification(event.type, event.ID, event.orderID); - }; - - wsSocket.onerror = function (error) {console.log('Alert Socket error on wsSocket: ' + error);}; + $.when($.get('/setup/getAlertPort')).done(function (port) + { + console.log('alert port is: '+port.port); alertPort = port.port; + let wsSocket = new WebSocket('ws://localhost:'+alertPort); + wsSocket.onopen = function () {wsSocket.send('connected to alerts');}; + wsSocket.onmessage = function (message) { + console.log(message.data); + let event = JSON.parse(message.data); + addNotification(event.type, event.ID, event.orderID); + }; + wsSocket.onerror = function (error) {console.log('Alert Socket error on wsSocket: ' + error);}; }); - } + } } /** * get the finance alert web socket port */ function getFinanceAlertPort () { - if (financeAlertPort == null) - { - $.when($.get('/setup/getFinanceAlertPort')).done(function (port) + if (financeAlertPort === null) { - console.log('finance alert port is: '+port.port); financeAlertPort = port.port; - var wsSocket = new WebSocket('ws://localhost:'+financeAlertPort); - wsSocket.onopen = function () {wsSocket.send('connected to finance alerts');}; - wsSocket.onmessage = function (message) { - console.log(message.data); - var event = JSON.parse(message.data); - addNotification(event.type, event.ID, event.orderID); - }; - - wsSocket.onerror = function (error) {console.log('Finance Alert Socket error on wsSocket: ' + error);}; + $.when($.get('/setup/getFinanceAlertPort')).done(function (port) + { + console.log('finance alert port is: '+port.port); financeAlertPort = port.port; + let wsSocket = new WebSocket('ws://localhost:'+financeAlertPort); + wsSocket.onopen = function () {wsSocket.send('connected to finance alerts');}; + wsSocket.onmessage = function (message) { + console.log(message.data); + let event = JSON.parse(message.data); + addNotification(event.type, event.ID, event.orderID); + }; + wsSocket.onerror = function (error) {console.log('Finance Alert Socket error on wsSocket: ' + error);}; }); - } + } } + /** - * alert processing + * + * @param {Event} _event - inbound Event + * @param {String} _id - subscriber target + * @param {String} _orderID - inbound order id */ function addNotification(_event, _id, _orderID) { - var method = 'showNotification'; - console.log(method+' _event'+_event+' id: '+_id+' orderID: '+_orderID); - type = getSubscriber(_id) - if (type == 'none') {return} - switch(type) - { + let method = 'showNotification'; + console.log(method+' _event'+_event+' id: '+_id+' orderID: '+_orderID); + let type = getSubscriber(_id); + if (type === 'none') {return;} + switch(type) + { case 'Buyer': - b_alerts.push({'event': _event, 'order': _orderID}); - toggleAlert(b_notify, b_alerts, b_count); - break; + b_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(b_notify, b_alerts, b_count); + break; case 'Seller': - s_alerts.push({'event': _event, 'order': _orderID}); - toggleAlert(s_notify, s_alerts, s_count); - break; + s_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(s_notify, s_alerts, s_count); + break; case 'Provider': - p_alerts.push({'event': _event, 'order': _orderID}); - toggleAlert(p_notify, p_alerts, p_count); - break; + p_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(p_notify, p_alerts, p_count); + break; case 'Shipper': - sh_alerts.push({'event': _event, 'order': _orderID}); - toggleAlert(sh_notify, sh_alerts, sh_count); - break; + sh_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(sh_notify, sh_alerts, sh_count); + break; case 'FinanceCo': - f_alerts.push({'event': _event, 'order': _orderID}); - toggleAlert(f_notify, f_alerts, f_count); - break; + f_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(f_notify, f_alerts, f_count); + break; default: - console.log(method+' default entered for: '+type); - break; - } + console.log(method+' default entered for: '+type); + break; + } } /** - * alert toggle + * + * @param {jQuery} _target - jquery object to update + * @param {Array} _array - array of alerts for this member + * @param {jQuery} _count - jQuery object to hold alert count */ function toggleAlert(_target, _array, _count) { - if (_array.length < 1) - {$(_target).removeClass('on'); $(_target).addClass('off'); } - else {$(_count).empty(); $(_count).append(_array.length); - $(_target).removeClass('off'); $(_target).addClass('on'); } + if (_array.length < 1) + {$(_target).removeClass('on'); $(_target).addClass('off'); } + else {$(_count).empty(); $(_count).append(_array.length); + $(_target).removeClass('off'); $(_target).addClass('on'); } } /** * check to see if _id is subscribing + * @param {Integer} _id - member id to seek + * @returns {String} - type of member */ function getSubscriber(_id) { - var type = 'none'; - for (each in subscribers){(function(_idx, _arr){if (_arr[_idx].id == _id){type=_arr[_idx].type;}})(each, subscribers)} - return(type); + let type = 'none'; + for (let each in subscribers){(function(_idx, _arr){if (_arr[_idx].id === _id){type=_arr[_idx].type;}})(each, subscribers);} + return(type); } /** * subscribe to events - * - * + * @param {String} _type - member type + * @param {String} _id - member id */ function z2bSubscribe(_type, _id) { - subscribers.push({'type': _type, 'id': _id}); + subscribers.push({'type': _type, 'id': _id}); } /** - * unsubscribe to events - * - * + * Unsubscribe to events + * @param {String} _id - member id to remove */ function z2bUnSubscribe(_id) { - var _s1 = subscribers; - var _s2 = []; - for (each in _s1) {(function(_idx, _arr){if (_arr[_idx] != _id){_s2.push(_arr[_idx])}})(each, _s1)} - subscribers = _s2; + let _s1 = subscribers; + let _s2 = []; + for (let each in _s1) {(function(_idx, _arr){if (_arr[_idx] != _id){_s2.push(_arr[_idx]);}})(each, _s1);} + subscribers = _s2; } /** * notifyMe + * @param {Array} _alerts - array of alerts * @param {String} _id - orderID + * @returns {Boolean} - true if found, false if not found */ function notifyMe (_alerts, _id) { - var b_h = false; - for (each in _alerts) {(function(_idx, _arr){if (_id === _arr[_idx].order){b_h = true;}})(each, _alerts)} - return b_h; + let b_h = false; + for (let each in _alerts) {(function(_idx, _arr){if (_id === _arr[_idx].order){b_h = true;}})(each, _alerts);} + return b_h; } \ No newline at end of file diff --git a/Chapter12/Documentation/answers/js/z2b-financeCo_complete.js b/Chapter12/Documentation/answers/js/z2b-financeCo_complete.js index 46d0728..e0c3685 100644 --- a/Chapter12/Documentation/answers/js/z2b-financeCo_complete.js +++ b/Chapter12/Documentation/answers/js/z2b-financeCo_complete.js @@ -14,200 +14,214 @@ // z2c-financeCo.js -var financeCOorderDiv = "financeCOorderDiv"; -var orders = []; +'use strict'; + +let financeCOorderDiv = 'financeCOorderDiv'; +let orders = []; const financeCoID = 'easymoney@easymoneyinc.com'; const financeCoName = 'The Global Financier'; -var f_notify = '#financeCo_notify'; -var f_id = 'easymoney@easymoneyinc.com'; -var f_count = '#financeCo_count'; -var f_alerts; - +let f_notify = '#financeCo_notify'; +let f_id = 'easymoney@easymoneyinc.com'; +let f_count = '#financeCo_count'; +let f_alerts; /** - * load the administration User Experience + * load the finance company User Experience */ function loadFinanceCoUX () { - toLoad = "financeCo.html"; - // get the FinanceAlert Port - getFinanceAlertPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupFinanceCo(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupFinanceCo(page[0], port[0]);}); - } + let toLoad = 'financeCo.html'; + // get the FinanceAlert Port + getFinanceAlertPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) + {setupFinanceCo(page[0], port[0]);}); + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupFinanceCo(page[0], port[0]);}); + } } - +/** + * @param {String} page HTML page to load + * @param {Integer} port Websocket port to use + */ function setupFinanceCo(page, port) { - $("#body").empty(); - $("#body").append(page); - f_alerts = []; - if (f_alerts.length == 0) - {$(f_notify).removeClass('on'); $(f_notify).addClass('off'); } - else - {$(f_notify).removeClass('off'); $(f_notify).addClass('on'); } - updatePage("financeCo"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('finance_messages', msgPort); - var _clear = $("#financeCOclear"); - var _list = $("#financeCOorderStatus"); - var _orderDiv = $("#"+financeCOorderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listFinanceOrders()}); - z2bSubscribe('FinanceCo', f_id); + $('#body').empty(); + $('#body').append(page); + f_alerts = []; + if (f_alerts.length === 0) + {$(f_notify).removeClass('on'); $(f_notify).addClass('off'); } + else + {$(f_notify).removeClass('off'); $(f_notify).addClass('on'); } + updatePage( 'financeCo'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('finance_messages', msgPort); + let _clear = $('#financeCOclear'); + let _list = $('#financeCOorderStatus'); + let _orderDiv = $('#'+financeCOorderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listFinanceOrders();}); + z2bSubscribe('FinanceCo', f_id); } /** - * lists all orders for the selected seller + * lists all orders for the selected financier */ function listFinanceOrders() { - var options = {}; - options.id = financeCoID; - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = financeCoID; + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#"+financeCOorderDiv).empty(); $("#"+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} - else{orders = _results.orders; formatFinanceOrders($("#"+financeCOorderDiv), orders)} - }); - }); + if (_results.orders.length < 1) {$('#'+financeCOorderDiv).empty(); $('#'+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} + else{orders = _results.orders; formatFinanceOrders($('#'+financeCOorderDiv), orders);} + }); } + /** * used by the listOrders() function - * formats the orders for a buyer. Orders to be formatted are provided in the _orders array + * formats the orders for a financier. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Integer} _orders - array with order objects */ function formatFinanceOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let p_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a financier can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - break; + _date = _arr[_idx].delivered; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - break; + _date = _arr[_idx].created; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - _action += '' - break; + _date = _arr[_idx].approved; + _action += ''; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - break; + _date = _arr[_idx].bought; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Refund.code: - _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; - break; + _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += '
'; - _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_arr[_idx].buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= formatDetail(_idx, _arr[_idx]); - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { - $("#f_order"+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#order"+_idx+"_b").on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#f_btn_"+_idx).on('click', function () + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + let _len = 'resource:org.acme.Z2BTestNetwork.Buyer#'.length; + let _buyer = _arr[_idx].buyer.substring(_len, _arr[_idx].buyer.length); + _str += '
'; + _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= formatDetail(_idx, _arr[_idx]); + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) { - var options = {}; - options.action = $("#f_action"+_idx).find(":selected").text(); - options.orderNo = $("#f_order"+_idx).text(); - options.participant = financeCoID; - console.log(options); - $("#finance_messages").prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#finance_messages").prepend(formatMessage(_results.result)); - }); - }); - if (notifyMe(f_alerts, _arr[_idx].id)) {$("#f_status"+_idx).addClass('highlight'); } - })(each, _orders) - } - f_alerts = new Array(); - toggleAlert($('#financeCo_notify'), f_alerts, f_alerts.length); + $('#f_order'+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#order'+_idx+'_b').on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#f_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#f_action'+_idx).find(':selected').text(); + options.orderNo = $('#f_order'+_idx).text(); + options.participant = financeCoID; + console.log(options); + $('#finance_messages').prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#finance_messages').prepend(formatMessage(_results.result)); + }); + }); + if (notifyMe(f_alerts, _arr[_idx].id)) {$("#f_status"+_idx).addClass('highlight'); } + })(each, _orders); + } + f_alerts = new Array(); + toggleAlert($('#financeCo_notify'), f_alerts, f_alerts.length); } /** * format the accordian with the details for this order + * @param {Integer} _cur - offset into order array + * @param {JSON} _order - JSON object with current order data + * @returns {String} - html string to append to browser page */ function formatDetail(_cur, _order) { - console.log('['+_cur+'] is ',_order); - var _out = '
'; - _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; - _out += ''; - _out += ''; - _out += (_order.cancelled === "") ? '' : ''; - _out += (_order.bought === "") ? '' : ''; - _out += (_order.ordered === "") ? '' : ''; - _out += (_order.dateBackordered === "") ? '' : ''; - _out += (_order.requestShipment === "") ? '' : ''; - _out += (_order.delivering === "") ? '' : ''; - _out += (_order.delivered === "") ? '' : ''; - _out += (_order.paymentRequested === "") ? '' : ''; - _out += (_order.disputeOpened === "") ? '' : ''; - if (_order.disputeResolved === "") - { - if (_order.disputeOpened === "") - {_out += '';} + console.log('['+_cur+'] is ',_order); + let _out = '
'; + _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; + _out += '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
'; + _out += ''; + _out += (_order.cancelled === '') ? '' : ''; + _out += (_order.bought === '') ? '' : ''; + _out += (_order.ordered === '') ? '' : ''; + _out += (_order.dateBackordered === '') ? '' : ''; + _out += (_order.requestShipment === '') ? '' : ''; + _out += (_order.delivering === '') ? '' : ''; + _out += (_order.delivered === '') ? '' : ''; + _out += (_order.paymentRequested === '') ? '' : ''; + _out += (_order.disputeOpened === '') ? '' : ''; + if (_order.disputeResolved === '') + { + if (_order.disputeOpened === '') + {_out += '';} + else + {_out += '';} + } else - {_out += '';} - } - else - {_out +='';} - _out += (_order.orderRefunded === "") ? '' : ''; - _out += (_order.approved === "") ? '' : ''; - _out += (_order.paid === "") ? '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
Dispute ResolvedDispute is Unresolved
Dispute ResolvedDispute is Unresolved
Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'
Refund?(No Refund in Process)
Refund?'+_order.orderRefunded+''+_order.refund+'
Payment Approved(No Approval from Buyer)
Payment Approved'+_order.buyer+''+_order.approved+'
Paid(UnPaid)
' : 'Paid'+_order.financeCo+''+_order.paid+'
'; - return _out; + {_out +='Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'';} + _out += (_order.orderRefunded === '') ? 'Refund?(No Refund in Process)' : 'Refund?'+_order.orderRefunded+''+_order.refund+''; + _out += (_order.approved === '') ? 'Payment Approved(No Approval from Buyer)' : 'Payment Approved'+_order.buyer+''+_order.approved+''; + _out += (_order.paid === '') ? 'Paid(UnPaid)' : 'Paid'+_order.financeCo+''+_order.paid+''; + return _out; } diff --git a/Chapter12/HTML/CSS/pageStyles.css b/Chapter12/HTML/CSS/pageStyles.css index 35064a3..69f4ecc 100755 --- a/Chapter12/HTML/CSS/pageStyles.css +++ b/Chapter12/HTML/CSS/pageStyles.css @@ -18,7 +18,7 @@ body {height: 100%} overflow: auto; } .button-wide { - width: 30%; + width: 15%; color: blue; font-size: 1em; text-align: center; @@ -88,17 +88,43 @@ body {height: 100%} } } .highlight { - + border: .125em solid rgb(88, 8, 235); + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + border-radius: .5em; + background-color: rgb(252, 245, 151); + font-weight: bold; } .notify.on { - -} + border-radius: 100%; + height: 2em; + width: 2em; + background-color: rgba(226, 32, 91, 0.77); + color: #ffffff; + text-align: top; + position: relative; + top: .4em; + float: right; + right: .5em; + visibility: visible; + } .notify.off { visibility: hidden; } .n_count.on { font-size: .5em; font-weight: bold; visibility: visible;} .n_count.off { font-size: .5em; font-weight: bold; visibility: hidden;} h2 {font-size: 1.5em; margin-top: .25em; margin-bottom: .25em;} + .strike { + position: relative; +} +.strike::before { + content: ''; + border-bottom: 2px solid rgb(232, 235, 65); + width: 100%; + position: absolute; + right: 0; + top: 50%; +} .buyer { background-color: #CBCFD0; } .seller { background-color: rgb(173, 242, 173);} .provider { background-color: rgb(192, 221, 252);} diff --git a/Chapter12/HTML/admin.html b/Chapter12/HTML/admin.html index a010464..53b3a2d 100644 --- a/Chapter12/HTML/admin.html +++ b/Chapter12/HTML/admin.html @@ -1,41 +1,45 @@

-
-

- - - - - -
(
-

- - - - - - - - -
-

- - - - - - +

Why All The Changes?

+
+

+
y
+ + + +
(
-

- - - - +

+
+ + + + + + +
-
-
-

Result

-
-
+

+ + + + + + + + + +
y
+

+ + + + +
+
+
+
+
+
- + \ No newline at end of file diff --git a/Chapter12/HTML/adminHelp.html b/Chapter12/HTML/adminHelp.html new file mode 100644 index 0000000..f1cf21c --- /dev/null +++ b/Chapter12/HTML/adminHelp.html @@ -0,0 +1,29 @@ +

Why All The Changes?

+

HyperLedger Composer has gone through two significant changes in 4Q2017. + The first, Version 0.14, changed how security worked and clarified the difference between the business network administrator (admin) and +the fabric Administrator (PeerAdmin). While this had little effect on what the Admin user interface could do, it did +change significantly how the underlying code worked in the hlcAdmin.js file and in the autoLoad.js file. The biggest code change +is that the autoLoad process started issuing Identities instead of just adding members to the registry. The other significant +change required adding two statements to the permissions.acl file. +

+

Then Version 0.15 was released and the entire access structure was changed from connection profile + username/password (which is why we had the getSecret() method) + to idCards. This necessitated changes in some of the scripts we use (buildAndDeploy, startup.sh, deployNetwork.sh), + required a complete rewrite for how the test code loads and connects to the network and also required changes in the admin + interface. You'll see a number of items which have a yellow strikethrough, indicating that they + are no longer available. +

+

We aren't using connection profiles any more as part of the log in process, so that whole section is no longer useful. + Because we're using cards, we don't need to use, nor do we need to capture, the user secrets associated with each + Member. so that is deactivated. +

+

We do, however, need more capability for Members. Along with the Add Member function, which we've had all along, we now need + the ability to issue an Identity for that Member and then to create an idCard for that member. You'll see those new + functions in the Resource Management part of the administrative user interface, along with a feature which will + check to see if an idCard already exists for a specific member. +

+

An Identity can only be issued for an existing Member, so the process is to:

+ Creating an idCard requires the password, or secret, which was generated during the issue Identity process. Each of these + functions has been implemented individually. It would be a great idea to combine the issue Identity process with the Create idCard + process, so that you don't have to remember to copy the generated secret and type it into the createCard page. +

\ No newline at end of file diff --git a/Chapter12/HTML/buyer.html b/Chapter12/HTML/buyer.html index 646b482..34b35c9 100644 --- a/Chapter12/HTML/buyer.html +++ b/Chapter12/HTML/buyer.html @@ -1,6 +1,6 @@

- +
1
diff --git a/Chapter12/HTML/favicon.ico b/Chapter12/HTML/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter12/HTML/favicon.ico and b/Chapter12/HTML/favicon.ico differ diff --git a/Chapter12/HTML/financeCo.html b/Chapter12/HTML/financeCo.html index 1886890..4003b2a 100644 --- a/Chapter12/HTML/financeCo.html +++ b/Chapter12/HTML/financeCo.html @@ -1,6 +1,6 @@

-
+
1
diff --git a/Chapter12/HTML/fonts/glyphicons-halflings-regular.ttf b/Chapter12/HTML/fonts/glyphicons-halflings-regular.ttf index 1413fc6..1f85312 100644 Binary files a/Chapter12/HTML/fonts/glyphicons-halflings-regular.ttf and b/Chapter12/HTML/fonts/glyphicons-halflings-regular.ttf differ diff --git a/Chapter12/HTML/icons/Search.ico b/Chapter12/HTML/icons/Search.ico index e1d39ae..fd437a0 100755 Binary files a/Chapter12/HTML/icons/Search.ico and b/Chapter12/HTML/icons/Search.ico differ diff --git a/Chapter12/HTML/js/z2b-admin.js b/Chapter12/HTML/js/z2b-admin.js index c716cb8..67f421a 100644 --- a/Chapter12/HTML/js/z2b-admin.js +++ b/Chapter12/HTML/js/z2b-admin.js @@ -14,57 +14,53 @@ // z2b-admin.js -var creds; -var connection; -var connectionProfileName = 'z2b-test-profile'; -var networkFile = 'zerotoblockchain-network.bna' -var businessNetwork = 'zerotoblockchain-network'; -var msgPort = null; -var _blctr = 0; +'use strict'; + +let creds; +let connection; +let msgPort = null; +let _blctr = 0; /** * load the administration User Experience */ function loadAdminUX () { - toLoad = 'admin.html'; - $.when($.get(toLoad)).done(function (page) - {$('#body').empty(); - $('#body').append(page); - updatePage("admin"); - listMemRegistries(); - }); + let toLoad = 'admin.html'; + $.when($.get(toLoad)).done(function (page) + {$('#body').empty(); + $('#body').append(page); + updatePage('admin'); + listMemRegistries(); + }); } /** * connect to the provided web socket - * @param {loc} - _target location to post messages - * @param {port} - web socket port # + * @param {String} _target - location to post messages + * @param {Integer} _port - web socket port # */ function wsDisplay(_target, _port) { - var content = $('#'+_target); - var wsSocket = new WebSocket('ws://localhost:'+_port); - wsSocket.onopen = function () {wsSocket.send('connected to client');}; - - wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; - - wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; - + let content = $('#'+_target); + let wsSocket = new WebSocket('ws://localhost:'+_port); + wsSocket.onopen = function () {wsSocket.send('connected to client');}; + wsSocket.onmessage = function (message) {content.append(formatMessage(message.data));}; + wsSocket.onerror = function (error) {console.log('WebSocket error on wsSocket: ' + error);}; } /** * list the available business networks */ function adminList() { - var _url = '/composer/admin/listAsAdmin'; - $.when($.get(_url)).done(function (_connection) - { var _str = '

Current Active Business Networks

    '; - for (each in _connection) - {(function(_idx, _arr){_str += '
  • '+_arr[_idx]+'
  • ';})(each, _connection)} - _str+='
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + let _url = '/composer/admin/listAsAdmin'; + $.when($.get(_url)).done(function (_connection) + { let _str = '

Current Active Business Networks

    '; + for (let each in _connection) + {(function(_idx, _arr){_str += '
  • '+_arr[_idx]+'
  • ';})(each, _connection);} + _str+='
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -72,57 +68,56 @@ function adminList() */ function displayProfileForm () { - toLoad = 'createConnectionProfile.html'; - $.when($.get(toLoad)).done(function (page) - {$('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("createConnectionProfile"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){var _vals = getConnectForm(); createConnection(_vals);}); - }); + let toLoad = 'createConnectionProfile.html'; + $.when($.get(toLoad)).done(function (page) + {$('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('createConnectionProfile'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){let _vals = getConnectForm(); createConnection(_vals);}); + }); } /** - * get the data from the network connection form. + * get the data from the network connection form. + * @returns {JSON} - JSON object with connection data; */ function getConnectForm () { - var fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; - var res = {} - - res['profileName'] = $('#profileName').val(); - for (each in fields) - {(function (_idx, _arr){ - if (_arr[_idx] == 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} - else - { var parts = _arr[_idx].split('_'); - if (parts.length == 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} - if (typeof(res[parts[0]]) == 'undefined') {res[parts[0]]={};} - res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); - } - })(each, fields) } + let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', 'keyValStore', 'channel', 'mspID', 'timeout']; + let res = {}; + + res.profileName = $('#profileName').val(); + for (let each in fields) + {(function (_idx, _arr){ + if (_arr[_idx] === 'fabric_type') {res['type'] = $('#'+_arr[_idx]).val();} + else + { let parts = _arr[_idx].split('_'); + if (parts.length === 1) {res[_arr[_idx]] = $('#'+_arr[_idx]).val();} + if (typeof(res[parts[0]]) === 'undefined') {res[parts[0]]={};} + res[parts[0]][parts[1]] = $('#'+_arr[_idx]).val(); + } + })(each, fields); } return res; } /** * test creating a network connection - * @param {networkConnectionData} - Data from the form used to populate a hyperledger fabric V1 network connection. + * @param {Form} _form - Data from the form used to populate a hyperledger fabric V1 network connection. */ function createConnection (_form) -{ -console.log(_form); -$.when($.post('/composer/admin/createProfile', _form)).done(function(_results) -{ - var _str = ''; - _str +='

network profile creation request

'; - _str += '

Creation request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - -}); - +{ + console.log(_form); + $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) + { + let _str = ''; + _str +='

network profile creation request

'; + _str += '

Creation request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -130,55 +125,55 @@ $.when($.post('/composer/admin/createProfile', _form)).done(function(_results) */ function getProfiles() { - $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) - { - var _str = ''; - // list cert URL & cert path - _str +='

network connection profile list request

'; - _str += '
    '; - for (each in _profiles) {_str += displayProfile(_profiles[each], each)} - _str += '
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - - }); + $.when($.get('/composer/admin/getAllProfiles')).done(function (_profiles) + { + let _str = ''; + // list cert URL & cert path + _str +='

network connection profile list request

'; + _str += '
    '; + for (let each in _profiles) {_str += displayProfile(_profiles[each], each);} + _str += '
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + + }); } /** * gather and list all of the current network connection profiles - * @param {integer} - _state is a switch, if it == 0 (zero) then display the deleteConnection button, else hide that button. - * This allows the same routine to be used for display or delete processing + * @param {integer} - _state is a switch, if it === 0 (zero) then display the deleteConnection button, else hide that button. + * This allows the same routine to be used for display or delete processing */ function listProfiles(_state) { - $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(page); - updatePage("deleteConnectionProfile"); - $('#connection_profiles').on('change',function() - { var name = $('#connection_profiles').find(':selected').text(); - var profile = connection_profiles[name]; - var _str = displayProfile(profile,name); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); + $.when($.get('/composer/admin/getAllProfiles'), $.get('deleteConnectionProfile.html')).done(function (_profiles, page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(page); + updatePage('deleteConnectionProfile'); + $('#connection_profiles').on('change',function() + { let name = $('#connection_profiles').find(':selected').text(); + let profile = connection_profiles[name]; + let _str = displayProfile(profile,name); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + }); + let connection_profiles = _profiles[0]; + for (let each in connection_profiles) + { (function (_idx, _arr) + { $('#connection_profiles').append(''); })(each, connection_profiles); } + let first = $('#connection_profiles').find(':first').text(); + let _str = displayProfile(connection_profiles[first],first); + $('#selected_profile').empty(); + $('#selected_profile').append(_str); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + if (_state === 0) + {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} + else + {_submit.hide();} }); - var connection_profiles = _profiles[0]; - for (each in connection_profiles) - { (function (_idx, _arr) - { $('#connection_profiles').append(''); })(each, connection_profiles); } - var first = $('#connection_profiles').find(':first').text(); - var _str = displayProfile(connection_profiles[first],first); - $('#selected_profile').empty(); - $('#selected_profile').append(_str); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - if (_state == 0) - {_submit.on('click', function(){deleteConnectionProfile($('#connection_profiles').find(':selected').text());});} - else - {_submit.hide();} - }); } /** @@ -186,15 +181,15 @@ function listProfiles(_state) */ function networkDeploy() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/deploy', options)).done(function (_results) - { var _str = ''; - _str +='

network deploy request for '+networkFile+'

'; - _str += '

Network deploy results: '+_results.deploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/deploy', options)).done(function (_results) + { let _str = ''; + _str +='

network deploy request for '+networkFile+'

'; + _str += '

Network deploy results: '+_results.deploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -202,15 +197,15 @@ function networkDeploy() */ function networkInstall() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/install', options)).done(function (_results) - { var _str = ''; - _str +='

network install request for '+networkFile+'

'; - _str += '

Network install results: '+_results.install+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/install', options)).done(function (_results) + { let _str = ''; + _str +='

network install request for '+networkFile+'

'; + _str += '

Network install results: '+_results.install+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -218,15 +213,15 @@ function networkInstall() */ function networkStart() { - var options = {}; - options.myArchive = networkName; - $.when($.post('/composer/admin/start', options)).done(function (_results) - { var _str = ''; - _str +='

network start request for '+networkName+'

'; - _str += '

Network start results: '+_results.start+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkName; + $.when($.post('/composer/admin/start', options)).done(function (_results) + { let _str = ''; + _str +='

network start request for '+networkName+'

'; + _str += '

Network start results: '+_results.start+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** @@ -235,23 +230,23 @@ function networkStart() */ function deleteConnectionProfile(_name) { - var options = {}; - options.profileName = _name; - if (confirm('Are you sure you want to delete the '+_name+' profile?') == true) - { - $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + let options = {}; + options.profileName = _name; + if (confirm('Are you sure you want to delete the '+_name+' profile?') === true) { - var _str = ''; - _str +='

network profile delete request for '+_name+'

'; - _str += '

Profile delete request results: '+_results.profile+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('request cancelled'); - } + $.when($.post('/composer/admin/deleteProfile', options)).done(function(_results) + { + let _str = ''; + _str +='

network profile delete request for '+_name+'

'; + _str += '

Profile delete request results: '+_results.profile+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('request cancelled'); + } } /** @@ -259,16 +254,16 @@ function deleteConnectionProfile(_name) */ function ping() { - var options = {}; options.businessNetwork = businessNetwork; - $.when($.post('/composer/admin/ping', options)).done(function (_results) - { - var _str = ''; - _str +='

network ping request to '+businessNetwork+'

'; - _str += '

Ping request results: '+'

'; - for (each in _results.ping){(function(_idx, _arr){_str+=''})(each, _results.ping)} - _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); + let options = {}; options.businessNetwork = businessNetwork; + $.when($.post('/composer/admin/ping', options)).done(function (_results) + { + let _str = ''; + _str +='

network ping request to '+businessNetwork+'

'; + _str += '

Ping request results: '+'

'; + for (let each in _results.ping){(function(_idx, _arr){_str+='';})(each, _results.ping);} + _str+='
ItemValue
'+_idx+''+_arr[_idx]+'
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); }); } @@ -277,25 +272,23 @@ function ping() */ function networkUndeploy() { - - var options = {}; - options.businessNetwork = businessNetwork; - if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') == true) - { - $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + let options = {}; + options.businessNetwork = businessNetwork; + if (confirm('Are you sure you want to undeploy the '+businessNetwork+' business network?') === true) { - var _str = ''; - _str +='

Network undeploy request for '+businessNetwork+'

'; - _str += '

Network Undeploy request results: '+_results.undeploy+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); - } else - { - $('#message').empty(); - $('#message').append('undeploy request cancelled'); - } - + $.when($.post('/composer/admin/undeploy', options)).done(function(_results) + { + let _str = ''; + _str +='

Network undeploy request for '+businessNetwork+'

'; + _str += '

Network Undeploy request results: '+_results.undeploy+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); + } else + { + $('#message').empty(); + $('#message').append('undeploy request cancelled'); + } } /** @@ -303,354 +296,486 @@ function networkUndeploy() */ function networkUpdate() { - var options = {}; - options.myArchive = networkFile; - $.when($.post('/composer/admin/update', options)).done(function (_results) - { var _str = ''; - _str +='

network update request for '+networkFile+'

'; - _str += '

Network update results: '+_results.update+'

'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); -}); + let options = {}; + options.myArchive = networkFile; + $.when($.post('/composer/admin/update', options)).done(function (_results) + { let _str = ''; + _str +='

network update request for '+networkFile+'

'; + _str += '

Network update results: '+_results.update+'

'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* display a network profile -*/ +/** + * display a network profile + * @param {JSON} _profile - profile object + * @param {String} _name - name of profile to display + * @returns {String} - html to be appended to current object + */ function displayProfile(_profile, _name) { - var _str = ''; - _str += '

'+_name+'

'; - _str +=''; - for (item in _profile) - {(function(_item, _obj){ - switch (_item) - { - case 'orderers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); - } - break; - case 'peers': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - _str+=''; - })(subItem, _obj[_item]); - } - break; - case 'ca': - for (subItem in _obj[_item]) - {(function(_subItem, __obj) - {_str+=''; - })(subItem, _obj[_item]); + let _str = ''; + _str += '

'+_name+'

'; + _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'; + for (let item in _profile) + {(function(_item, _obj){ + switch (_item) + { + case 'orderers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + case 'peers': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + _str+=''; + })(subItem, _obj[_item]); + } + break; + case 'ca': + for (let subItem in _obj[_item]) + {(function(_subItem, __obj) + {_str+=''; + })(subItem, _obj[_item]); + } + break; + default: + _str+=''; } - break; - default: - _str+=''; - } - })(item, _profile) - } - _str +='
'+_item+'url'+__obj[_subItem].url+'
'+_item+'eventURL'+__obj[_subItem].eventURL+'
'+_item+'requestURL'+__obj[_subItem].requestURL+'
'+_item+''+_subItem+''+__obj[_subItem]+'
'+_item+''+_obj[_item]+'
'+_item+''+_obj[_item]+'
'; - return _str; + })(item, _profile); + } + _str +=''; + return _str; } -/* -* pre-load network from startup folder contents -*/ +/** + * pre-load network from startup folder contents + */ function preLoad() { - $('#body').empty(); - var options = {}; - $.when($.post('/setup/autoLoad', options)).done(function (_results) - { msgPort = _results.port; wsDisplay('body', msgPort); }); + $('#body').empty(); + let options = {}; + $.when($.post('/setup/autoLoad', options)).done(function (_results) + { msgPort = _results.port; wsDisplay('body', msgPort); }); } -/* -* get member registries -*/ +/** + * get member registries + */ function listMemRegistries() { - $.when($.get('/composer/admin/getRegistries')).done(function (_results) - { - $('#registryName').empty(); - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += '
    '; - for (each in _results.registries) - {(function(_idx, _arr){ - _str += '
  • '+_arr[_idx]+'
  • '; - $('#registryName').append(''); - $('#registryName2').append(''); - $('#registryName3').append(''); - })(each, _results.registries)} - _str += '
'; - $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $.when($.get('/composer/admin/getRegistries')).done(function (_results) + { + $('#registryName').empty(); + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
    '; + for (let each in _results.registries) + {(function(_idx, _arr){ + _str += '
  • '+_arr[_idx]+'
  • '; + $('#registryName').append(''); + $('#registryName2').append(''); + $('#registryName3').append(''); + $('#registryName4').append(''); + $('#registryName5').append(''); + })(each, _results.registries);} + _str += '
'; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } -/* -* get member in a registry -*/ +/** + * get member in a registry + */ function listRegistry() { - var options = {}; - options.registry = $('#registryName').find(':selected').text(); - $.when($.post('/composer/admin/getMembers', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - _str += ''; - for (each in _results.members) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.members)} - _str += ''; + let options = {}; + options.registry = $('#registryName').find(':selected').text(); + $.when($.post('/composer/admin/getMembers', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; + for (let each in _results.members) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.members);} + _str += ''; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * check if member already has a card + */ +function checkCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('starting check member id request.')); + $.when($.post('/composer/admin/checkCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* get asset list -*/ -function listAssets() +/** + * issue Identity for a member + */ +function issueIdentity() { - let options = {}; - options.registry = 'Order'; - options.type='admin'; - $.when($.post('/composer/admin/getAssets', options)).done(function (_results) - { - var _str = ''; - _str +='

Registry List

'; - _str += '

Network update results: '+_results.result+'

'; - if (_results.result === 'success') - { - _str += '
TypeCompanyemail
'+_arr[_idx].type+''+_arr[_idx].companyName+''+_arr[_idx].id+'
'; - for (each in _results.orders) - {(function(_idx, _arr){ - _str += ''; - })(each, _results.orders)} - _str += ''; - } else {_str += '
'+results.error} + let options = {}; + let member_list; + options.registry = $('#registryName4').find(':selected').text(); $('#admin-forms').empty(); - $('#admin-forms').append(_str); - }); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + options.type = $('#member_type').text(); + console.log(options); + $('#messages').append(formatMessage('starting issue identity request.')); + $.when($.post('/composer/admin/issueIdentity', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? 'user id: '+_results.userID+'
secret: '+_results.secret : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); } -/* -* add a member to a registry -*/ +/** + * create an access card for a member + */ +function createCard() +{ + let options = {}; + let member_list; + options.registry = $('#registryName5').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members); + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.secret = $('#secret').val(); + options.id = $('#member_list').find(':selected').text(); + console.log(options); + $('#messages').append(formatMessage('starting member card creation request.')); + $.when($.post('/composer/admin/createCard', options)).done(function (_results) + { let _msg = ((_results.result === 'success') ? _results.card : _results.message); + $('#messages').append(formatMessage(_msg));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); + }); +} +/** + * get asset list + */ +function listAssets() +{ + let options = {}; + options.registry = 'Order'; + options.type='admin'; + $.when($.post('/composer/admin/getAssets', options)).done(function (_results) + { + let _str = ''; + _str +='

Registry List

'; + _str += '

Network update results: '+_results.result+'

'; + if (_results.result === 'success') + { + _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; + for (let each in _results.orders) + {(function(_idx, _arr){ + _str += ''; + })(each, _results.orders);} + _str += ''; + } else {_str += '
'+_results.error;} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * add a member to a registry + */ function addMember() { - var _fields = ['companyName', 'participant_id', 'member_type']; - - $.when($.get('createMember.html')).done(function (_page) - { - $('#admin-forms').empty(); - $('#admin-forms').append(_page); - updatePage("createMember"); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - $('#messages').empty(); - $('#messages').append('
Please fill in add member form.'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - $('#messages').append('
starting add member request.'); - - var options = {} - options.companyName = $('#companyName').val(); - options.id = $('#participant_id').val(); - options.type = $('#member_type').find(':selected').text(); - $.when($.post('/composer/admin/addMember', options)).done(function(_res) - { $('#messages').append(formatMessat(_res)); }); - }); -}); + $.when($.get('createMember.html')).done(function (_page) + { + $('#admin-forms').empty(); + $('#admin-forms').append(_page); + updatePage('createMember'); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + $('#messages').empty(); + $('#messages').append('
Please fill in add member form.'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + $('#messages').append('
starting add member request.'); + let options = {}; + options.companyName = $('#companyName').val(); + options.id = $('#participant_id').val(); + options.type = $('#member_type').find(':selected').text(); + $.when($.post('/composer/admin/addMember', options)).done(function(_res) + { $('#messages').append(formatMessage(_res)); }); + }); + }); } -/* -* remove a member from a registry -*/ +/** + * remove a member from a registry + */ function removeMember() { - var options = {}; - var member_list; - options.registry = $('#registryName2').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); - $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - $('#member_type').append(options.registry); - updatePage("removeMember"); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#member_list').find(':selected').remove(); - $('#messages').append(formatMessage('starting delete member request.')); - $.when($.post('/composer/admin/removeMember', options)).done(function (_results) - { $('#messages').append(formatMessage(_results));}); - }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); + let options = {}; + let member_list; + options.registry = $('#registryName2').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append(formatMessage('Getting Member List for '+options.registry+'.')); + $.when($.post('/composer/admin/getMembers', options),$.get('removeMember.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + $('#member_type').append(options.registry); + updatePage('removeMember'); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#member_list').find(':selected').remove(); + $('#messages').append(formatMessage('starting delete member request.')); + $.when($.post('/composer/admin/removeMember', options)).done(function (_results) + { $('#messages').append(formatMessage(_results));}); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); + }); }); - }); } -/* -* retrieve member secret -*/ +/** + * retrieve member secret + */ function getSecret() { - var options = {}; - var member_list; - options.registry = $('#registryName3').find(':selected').text(); - $('#admin-forms').empty(); - $('#messages').empty(); - $('#messages').append('
Getting Member List for '+options.registry+'.'); - $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) - { - $('#admin-forms').append(_page[0]); - updatePage("getMemberSecret"); - $('#member_type').append(options.registry); - member_list = _results[0].members; - for (each in _results[0].members) - {(function(_idx, _arr){ - $('#member_list').append(''); - })(each, _results[0].members) - } - var first = $('#member_list').find(':first').text(); - displayMember(first, member_list); - var _cancel = $('#cancel'); - var _submit = $('#submit'); - _cancel.on('click', function (){$('#admin-forms').empty();}); - _submit.on('click', function(){ - options.id = $('#member_list').find(':selected').text(); - $('#messages').append(formatMessage('getting member secret.')); - $.when($.post('/composer/admin/getSecret', options)).done(function (_results) - { - $('#secret').empty(); $('#secret').append(_results.secret); - $('#userID').empty(); $('#userID').append(_results.userID); - $('#messages').append(formatMessage(_results)); + let options = {}; + let member_list; + options.registry = $('#registryName3').find(':selected').text(); + $('#admin-forms').empty(); + $('#messages').empty(); + $('#messages').append('
Getting Member List for '+options.registry+'.'); + $.when($.post('/composer/admin/getMembers', options),$.get('getMemberSecret.html')).done(function (_results, _page) + { + $('#admin-forms').append(_page[0]); + updatePage('getMemberSecret'); + $('#member_type').append(options.registry); + member_list = _results[0].members; + for (let each in _results[0].members) + {(function(_idx, _arr){ + $('#member_list').append(''); + })(each, _results[0].members) + } + let first = $('#member_list').find(':first').text(); + displayMember(first, member_list); + let _cancel = $('#cancel'); + let _submit = $('#submit'); + _cancel.on('click', function (){$('#admin-forms').empty();}); + _submit.on('click', function(){ + options.id = $('#member_list').find(':selected').text(); + $('#messages').append(formatMessage('getting member secret.')); + $.when($.post('/composer/admin/getSecret', options)).done(function (_results) + { + $('#secret').empty(); $('#secret').append(_results.secret); + $('#userID').empty(); $('#userID').append(_results.userID); + $('#messages').append(formatMessage(_results)); + }); + }); + $('#member_list').on('change',function() + { let id = $('#member_list').find(':selected').text(); + displayMember(id, member_list); }); }); - $('#member_list').on('change',function() - { var id = $('#member_list').find(':selected').text(); - displayMember(id, member_list); - }); - }); } + /** * display member information using the provided id and table - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} id - string with member id + * @param {JSON} _list - array of JSON member objects */ - function displayMember(id, _list) { - var member = findMember(id, _list); - $('#companyName').empty(); - $('#companyName').append(member.companyName); - $('#participant_id').empty(); - $('#participant_id').append(member.id); + let member = findMember(id, _list); + $('#companyName').empty(); + $('#companyName').append(member.companyName); + $('#participant_id').empty(); + $('#participant_id').append(member.id); } /** * find the member identified by _id in the array of JSON objects identified by _list - * @param id - string with member id - * @param _list - array of JSON member objects + * @param {String} _id - string with member id + * @param {JSON} _list - array of JSON member objects + * @returns {JSON} - {'id': Member ID, 'companyName': 'not found ... or company name if found'} */ - function findMember(_id, _list) { - _mem = {'id': _id, 'companyName': 'not found'}; - for (each in _list){(function(_idx, _arr) - { - if (_arr[_idx].id == _id) - {_mem = _arr[_idx]; } - })(each, _list)} - return(_mem); + let _mem = {'id': _id, 'companyName': 'not found'}; + for (let each in _list){(function(_idx, _arr) + { + if (_arr[_idx].id === _id) + {_mem = _arr[_idx]; } + })(each, _list);} + return(_mem); } /** * get blockchain info */ - function getChainInfo() { - $.when($.get('fabric/getChainInfo')).done(function(_res) - { var _str = '

Get Chain Info: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current Hash: '+formatMessage(_res.currentHash); - _str+= '
  • High: '+_res.blockchain.height.high+'
  • Low: '+_res.blockchain.height.low+'
'} - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainInfo')).done(function(_res) + { let _str = '

Get Chain Info: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current Hash: '+formatMessage(_res.currentHash); + _str+= '
  • High: '+_res.blockchain.height.high+'
  • Low: '+_res.blockchain.height.low+'
';} + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } + /** * get History */ - function getHistorian() { - $.when($.get('fabric/getHistory')).done(function(_res) - { var _str = '

Get History Records: '+_res.result+'

'; - if (_res.result == "success") - {_str += 'Current length: '+formatMessage(_res.history.length); - _str += '
Order NumberCreatedStatusBuyer/SellerAmount
'+_arr[_idx].id+''+_arr[_idx].created+''+JSON.parse(_arr[_idx].status).text+''+_arr[_idx].buyer+'
'+_arr[_idx].seller+'
$'+_arr[_idx].amount+'.00
'; - _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); - for (each in _res.history) - {(function(_idx, _arr){ - var _row = _arr[_idx]; - _str += ''; - })(each, _res.history) - } - _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; - } - else - {_str += formatMessage(_res.message);} - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getHistory')).done(function(_res) + { let _str = '

Get History Records: '+_res.result+'

'; + if (_res.result === 'success') + {_str += 'Current length: '+formatMessage(_res.history.length); + _str += ''; + _res.history.sort(function(a,b){return (b.transactionTimestamp > a.transactionTimestamp) ? -1 : 1;}); + for (let each in _res.history) + {(function(_idx, _arr){ + let _row = _arr[_idx]; + _str += ''; + })(each, _res.history); + } + _str +='
Transaction IDTransaction TypeTimeStamp
'+_row.transactionId+''+_row.transactionType+''+_row.transactionTimestamp+'
'; + } + else + {_str += formatMessage(_res.message);} + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); } /** * display blockchain updates */ - function getChainEvents() { - $.when($.get('fabric/getChainEvents')).done(function(_res) - { var _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; - var content = $('#blockchain'); - var csSocket = new WebSocket('ws://localhost:'+_res.port); - csSocket.onopen = function () {csSocket.send('connected to client');}; - csSocket.onmessage = function (message) { - _blctr ++; - if (message.data != 'connected') - {$('#blockchain').append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); - if (_blctr > 4) {var leftPos = $('#blockchain').scrollLeft(); $('#blockchain').animate({scrollLeft: leftPos + 300}, 250);} - } - }; - csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; - $("#admin-forms").empty(); - $("#admin-forms").append(_str); - }); + $.when($.get('fabric/getChainEvents')).done(function(_res) + { let _str = '

Get Chain events requested. Sending to port: '+_res.port+'

'; + let content = $('#blockchain'); + let csSocket = new WebSocket('ws://localhost:'+_res.port); + csSocket.onopen = function () {csSocket.send('connected to client');}; + csSocket.onmessage = function (message) { + _blctr ++; + if (message.data !== 'connected') + {$(content).append('block '+JSON.parse(message.data).header.number+'
Hash: '+JSON.parse(message.data).header.data_hash+'
'); + if (_blctr > 4) {let leftPos = $(content).scrollLeft(); $(content).animate({scrollLeft: leftPos + 300}, 250);} + } + }; + csSocket.onerror = function (error) {console.log('WebSocket error: ' + error);}; + $('#admin-forms').empty(); + $('#admin-forms').append(_str); + }); +} +/** + * display blockchain updates + */ +function displayAdminUpdate() +{ + let toLoad = 'adminHelp.html'; + $.when($.get(toLoad)).done(function(_page){$('#admin-forms').empty(); $('#admin-forms').append(_page);}); } \ No newline at end of file diff --git a/Chapter12/HTML/js/z2b-buyer.js b/Chapter12/HTML/js/z2b-buyer.js index cfc4487..38cb645 100644 --- a/Chapter12/HTML/js/z2b-buyer.js +++ b/Chapter12/HTML/js/z2b-buyer.js @@ -14,331 +14,323 @@ // z2c-buyer.js -var orderDiv = "orderDiv"; -var itemTable = {}; -var newItems = []; -var totalAmount = 0; - -// create vars for the buyer to use for the notification process -var b_notify = '#buyer_notify'; -var b_count = '#buyer_count'; -var b_id = ''; -var b_alerts; +'use strict'; +let b_notify = '#buyer_notify'; +let b_count = '#buyer_count'; +let b_id = ''; +let b_alerts; +let orderDiv = 'orderDiv'; +let itemTable = {}; +let newItems = []; +let totalAmount = 0; /** - * load the administration User Experience + * load the Buyer User Experience */ function loadBuyerUX () { - // get the html page to load - toLoad = "buyer.html"; - // get the port to use for web socket communications with the server - getPort(); - // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero - // assume user has run autoLoad and rebuild member list - // if autoLoad not yet run, then member list length will still be zero - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupBuyer(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + // get the html page to load + let toLoad = 'buyer.html'; + // get the port to use for web socket communications with the server + getPort(); + // if (buyers.length === 0) then autoLoad() was not successfully run before this web app starts, so the sie of the buyer list is zero + // assume user has run autoLoad and rebuild member list + // if autoLoad not yet run, then member list length will still be zero + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupBuyer(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupBuyer(page[0], port[0]);}); + } } function setupBuyer(page, port) { - // empty the hetml element that will hold this page - $("#buyerbody").empty(); - $("#buyerbody").append(page); - - //set the alerts file to an empty array and update the html class appropriately - /* - * YOUR CODE HERE - * - */ - -// update the text on the page using the prompt data for the selected language - updatePage("buyer"); - msgPort = port.port; - // connect to the web socket and tell the web socket where to display messages - wsDisplay('buyer_messages', msgPort); - // enable the buttons to process an onClick event - var _create = $("#newOrder"); - var _list = $("#orderStatus"); - var _orderDiv = $("#"+orderDiv); - _create.on('click', function(){displayOrderForm();}); - _list.on('click', function(){listOrders()}); - $("#buyer").empty(); - // build the buer select HTML element - for (each in buyers) - {(function(_idx, _arr){ - $("#buyer").append('');; - })(each, buyers)} + // empty the hetml element that will hold this page + $('#buyerbody').empty(); + $('#buyerbody').append(page); + // empty the buyer alerts array + // =====> Your Code Goes Here <========= + // if there are no alerts, then remove the 'on' class and add the 'off' class + if (b_alerts.length === 0) + { + // =====> Your Code Goes Here <========= + } + else {$(b_notify).removeClass('off'); $(b_notify).addClass('on'); } + // update the text on the page using the prompt data for the selected language + updatePage('buyer'); + msgPort = port.port; + // connect to the web socket and tell the web socket where to display messages + wsDisplay('buyer_messages', msgPort); + // enable the buttons to process an onClick event + let _create = $('#newOrder'); + let _list = $('#orderStatus'); + let _orderDiv = $('#'+orderDiv); + _create.on('click', function(){displayOrderForm();}); + _list.on('click', function(){listOrders();}); + $('#buyer').empty(); + // build the buer select HTML element + for (let each in buyers) + {(function(_idx, _arr) + {$('#buyer').append('');})(each, buyers); + } // display the name of the current buyer - $("#company")[0].innerText = buyers[0].companyName; - // update the buyer id field - /* - * YOUR CODE HERE - * - */ - // subscribe to events - /* - * YOUR CODE HERE - * - */ - // create a function to execute when the user selects a different buyer - $("#buyer").on('change', function() - { _orderDiv.empty(); $("#buyer_messages").empty(); - $("#company")[0].innerText = findMember($("#buyer").find(":selected").text(),buyers).companyName; - // unsubscribe the current member - /* - * YOUR CODE HERE - * - */ - // update the buyer id field - /* - * YOUR CODE HERE - * - */ - // subscribe to events - /* - * YOUR CODE HERE - * - */ + $('#company')[0].innerText = buyers[0].companyName; + // save the current buyer id as b_id + // =====> Your Code Goes Here <========= + // subscribe to events + // =====> Your Code Goes Here <========= + // create a function to execute when the user selects a different buyer + $('#buyer').on('change', function() + { _orderDiv.empty(); $('#buyer_messages').empty(); + $('#company')[0].innerText = findMember($('#buyer').find(':selected').text(),buyers).companyName; + // unsubscribe the current buyer + // =====> Your Code Goes Here <========= + // get the new buyer id + // =====> Your Code Goes Here <========= + // subscribe the new buyer + // =====> Your Code Goes Here <========= }); } /** * Displays the create order form for the selected buyer */ - function displayOrderForm() -{ toLoad = "createOrder.html"; -totalAmount = 0; -newItems = []; -// get the order creation web page and also get all of the items that a user can select -$.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) - { - itemTable = _items[0].items; - let _orderDiv = $("#"+orderDiv); - _orderDiv.empty(); - _orderDiv.append(page[0]); - // update the page with the appropriate text for the selected language - updatePage('createOrder'); - $('#seller').empty(); - // populate the seller HTML select object. This string was built during the MemberLoad or deferredMemberLoad function call - $('#seller').append(s_string); - $('#seller').val($("#seller option:first").val()); - $('#orderNo').append('xxx'); - $('#status').append('New Order'); - $('#today').append(new Date().toISOString()); - $('#amount').append('$'+totalAmount+'.00'); - // build a select list for the items - var _str = ""; - for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} - $('#items').empty(); - $('#items').append(_str); - $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); - // hide the submit new order function until an item has been selected - $('#submitNewOrder').hide(); - $('#submitNewOrder').on('click', function () - { let options = {}; - options.buyer = $("#buyer").find(":selected").val(); - options.seller = $("#seller").find(":selected").val(); - options.items = newItems; - console.log(options); - _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); - $.when($.post('/composer/client/addOrder', options)).done(function(_res) - { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); - }); - // function to call when an item has been selected - $('#addItem').on('click', function () - { let _ptr = $("#items").find(":selected").val(); - // remove the just selected item so that it cannot be added twice. - $('#items').find(':selected').remove(); - // build a new item detail row in the display window - let _item = itemTable[_ptr]; - let len = newItems.length; - _str = ''+_item.itemNo+''+_item.itemDescription+'' - $('#itemTable').append(_str); - // set the initial item count to 1 - $('#count'+len).val(1); - // set the initial price to the price of one item - $('#price'+len).append("$"+_item.unitPrice+".00"); - // add an entry into an array for this newly added item - let _newItem = _item; - _newItem.extendedPrice = _item.unitPrice; - newItems[len] = _newItem; - newItems[len].quantity=1; - totalAmount += _newItem.extendedPrice; - // update the order amount with this new item - $('#amount').empty(); - $('#amount').append('$'+totalAmount+'.00'); - // function to update item detail row and total amount if itemm count is changed - $('#count'+len).on('change', function () - {let len = this.id.substring(5); - let qty = $('#count'+len).val(); - let price = newItems[len].unitPrice*qty; - let delta = price - newItems[len].extendedPrice; - totalAmount += delta; - $('#amount').empty(); +{ let toLoad = 'createOrder.html'; + totalAmount = 0; + newItems = []; + // get the order creation web page and also get all of the items that a user can select + $.when($.get(toLoad), $.get('/composer/client/getItemTable')).done(function (page, _items) + { + itemTable = _items[0].items; + let _orderDiv = $('#'+orderDiv); + _orderDiv.empty(); + _orderDiv.append(page[0]); + // update the page with the appropriate text for the selected language + updatePage('createOrder'); + $('#seller').empty(); + // populate the seller HTML select object. This string was built during the memberLoad or deferredMemberLoad function call + $('#seller').append(s_string); + $('#seller').val($('#seller option:first').val()); + $('#orderNo').append('xxx'); + $('#status').append('New Order'); + $('#today').append(new Date().toISOString()); $('#amount').append('$'+totalAmount+'.00'); - newItems[len].extendedPrice = price; - newItems[len].quantity=qty; - $('#price'+len).empty(); $('#price'+len).append("$"+price+".00"); - }); - $('#submitNewOrder').show(); - }); - }); + // build a select list for the items + let _str = ''; + for (let each in itemTable){(function(_idx, _arr){_str+=''})(each, itemTable)} + $('#items').empty(); + $('#items').append(_str); + $('#cancelNewOrder').on('click', function (){_orderDiv.empty();}); + // hide the submit new order function until an item has been selected + $('#submitNewOrder').hide(); + $('#submitNewOrder').on('click', function () + { let options = {}; + options.buyer = $('#buyer').find(':selected').val(); + options.seller = $('#seller').find(':selected').val(); + options.items = newItems; + console.log(options); + _orderDiv.empty(); _orderDiv.append(formatMessage(textPrompts.orderProcess.create_msg)); + $.when($.post('/composer/client/addOrder', options)).done(function(_res) + { _orderDiv.empty(); _orderDiv.append(formatMessage(_res.result)); console.log(_res);}); + }); + // function to call when an item has been selected + $('#addItem').on('click', function () + { let _ptr = $('#items').find(':selected').val(); + // remove the just selected item so that it cannot be added twice. + $('#items').find(':selected').remove(); + // build a new item detail row in the display window + let _item = itemTable[_ptr]; + let len = newItems.length; + _str = ''+_item.itemNo+''+_item.itemDescription+''; + $('#itemTable').append(_str); + // set the initial item count to 1 + $('#count'+len).val(1); + // set the initial price to the price of one item + $('#price'+len).append('$'+_item.unitPrice+'.00'); + // add an entry into an array for this newly added item + let _newItem = _item; + _newItem.extendedPrice = _item.unitPrice; + newItems[len] = _newItem; + newItems[len].quantity=1; + totalAmount += _newItem.extendedPrice; + // update the order amount with this new item + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + // function to update item detail row and total amount if itemm count is changed + $('#count'+len).on('change', function () + {let len = this.id.substring(5); + let qty = $('#count'+len).val(); + let price = newItems[len].unitPrice*qty; + let delta = price - newItems[len].extendedPrice; + totalAmount += delta; + $('#amount').empty(); + $('#amount').append('$'+totalAmount+'.00'); + newItems[len].extendedPrice = price; + newItems[len].quantity=qty; + $('#price'+len).empty(); $('#price'+len).append('$'+price+'.00'); + }); + $('#submitNewOrder').show(); + }); + }); } /** * lists all orders for the selected buyer */ function listOrders() { - var options = {}; - // get the users email address - options.id = $("#buyer").find(":selected").text(); - // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { + let options = {}; + // get the users email address + options.id = $('#buyer').find(':selected').text(); + // get their password from the server. This is clearly not something we would do in production, but enables us to demo more easily + // $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) + // { // get their orders - options.userID = _mem.userID; options.secret = _mem.secret; + options.userID = options.id; + // options.userID = _mem.userID; options.secret = _mem.secret; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - // if they have no orders, then display a message to that effect - if (_results.orders.length < 1) {$("#orderDiv").empty(); $("#orderDiv").append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} - // if they have orders, format and display the orders. - else{formatOrders($("#orderDiv"), _results.orders)} - }); - }); + { + if ((typeof(_results.orders) === 'undefined') || (_results.orders === null)) + {console.log('error getting orders: ', _results);} + else + {// if they have no orders, then display a message to that effect + if (_results.orders.length < 1) {$('#orderDiv').empty(); $('#orderDiv').append(formatMessage(textPrompts.orderProcess.b_no_order_msg+options.id));} + // if they have orders, format and display the orders. + else{formatOrders($('#orderDiv'), _results.orders);} + } + }); + // }); } + /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + let r_string; + r_string = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - _action += ''; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].paymentRequested; + _action += ''; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; - break; + _date = _arr[_idx].delivered; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Dispute.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + r_string = '
'+textPrompts.orderProcess.Resolve.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - _action += '' - _action += '' - break; + _date = _arr[_idx].created; + _action += '' + _action += '' + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += '' - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += '' + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - break; + _date = _arr[_idx].approved; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += '' - break; + _date = _arr[_idx].bought; + _action += '' + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += '' - break; + _date = _arr[_idx].ordered; + _action += '' + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) - } - _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; - })(each, _orders) - } - // append the newly built order table to the web page - _target.append(_str); - // - // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. - // iterate through the page and make all of the different parts of the page active. - // - for (let each in _orders) - {(function(_idx, _arr) - { $("#b_btn_"+_idx).on('click', function () + break; + } + let _button = ''; + _action += ''; + if (_idx > 0) {_str += '
';} + _str += ''; + _str += ''+_action+r_string+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.seller+findMember(_arr[_idx].seller.split('#')[1],sellers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) { - var options = {}; - options.action = $("#b_action"+_idx).find(":selected").text(); - options.orderNo = $("#b_order"+_idx).text(); - options.participant = $("#buyer").val(); - if ((options.action == 'Dispute') || (options.action == 'Resolve')) {options.reason = $("#b_reason"+_idx).val();} - $("#buyer_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#buyer_messages").prepend(formatMessage(_results.result)); }); - }); - // using the notifyMe function in the events.js file, update the b_status+_idx HTML element appropriately - /* - * YOUR CODE HERE - * - */ -})(each, _orders) - } - b_alerts = new Array(); - toggleAlert($('#buyer_notify'), b_alerts, b_alerts.length); -} + (function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); + } + // append the newly built order table to the web page + _target.append(_str); + // + // now that the page has been placed into the browser, all of the id tags created in the previous routine can now be referenced. + // iterate through the page and make all of the different parts of the page active. + // + for (let each in _orders) + {(function(_idx, _arr) + { $('#b_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#b_action'+_idx).find(':selected').text(); + options.orderNo = $('#b_order'+_idx).text(); + options.participant = $('#buyer').val(); + if ((options.action === 'Dispute') || (options.action === 'Resolve')) + {options.reason = $('#b_reason'+_idx).val();} + $('#buyer_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { $('#buyer_messages').prepend(formatMessage(_results.result)); }); + }); + // use the notifyMe function to determine if this order is in the alert array. + // if it is, the highlight the $('#b_status'+_idx) html element by adding the 'highlight' class + // =====> Your Code Goes Here <========= +})(each, _orders); + } + // reset the b_alerts array to a new array + b_alerts = new Array(); + // call the toggleAlerts function to reset the alert icon + // =====> Your Code Goes Here <========= +} \ No newline at end of file diff --git a/Chapter12/HTML/js/z2b-events.js b/Chapter12/HTML/js/z2b-events.js index 0f1542e..fad87fa 100644 --- a/Chapter12/HTML/js/z2b-events.js +++ b/Chapter12/HTML/js/z2b-events.js @@ -13,41 +13,44 @@ */ // z2c-events.js -var alertPort = null; -var financeAlertPort = null; + +'use strict'; + +let alertPort = null; +let financeAlertPort = null; /** * load the four initial user roles into a single page. */ function singleUX () { - var toLoad = 'singleUX.html' - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) - { msgPort = _port.port; - $('#body').empty(); - $('#body').append(_page); - loadBuyerUX(); - loadSellerUX(); - loadProviderUX(); - loadShipperUX(); - // Initialize Registration for all Z2B Business Events - goEventInitialize(); + let toLoad = 'singleUX.html'; + if ((typeof(buyers) === 'undefined') || (buyers === null) || (buyers.length === 0)) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (_page, _port, _res) + { msgPort = _port.port; + $('#body').empty(); + $('#body').append(_page); + loadBuyerUX(); + loadSellerUX(); + loadProviderUX(); + loadShipperUX(); + // Initialize Registration for all Z2B Business Events + // =====> Your Code Goes Here <========= }); - } - else{ - $.when($.get(toLoad)).done(function(_page) - { - $('#body').empty(); - $('#body').append(_page); - loadBuyerUX(); - loadSellerUX(); - loadProviderUX(); - loadShipperUX(); - // Initialize Registration for all Z2B Business Events - goEventInitialize(); - }); - } + } + else{ + $.when($.get(toLoad)).done(function(_page) + { + $('#body').empty(); + $('#body').append(_page); + loadBuyerUX(); + loadSellerUX(); + loadProviderUX(); + loadShipperUX(); + // Initialize Registration for all Z2B Business Events + // =====> Your Code Goes Here <========= +}); + } } /** * load all of the members in the network for use in the different user experiences. This is a synchronous routine and is executed autormatically on web app start. @@ -55,35 +58,36 @@ function singleUX () */ function memberLoad () { - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = dropDummy(_buyers[0].members); - sellers = dropDummy(_sellers[0].members); - providers = dropDummy(_providers[0].members); - shippers = dropDummy(_shippers[0].members); - s_string = _getMembers(sellers); - p_string = _getMembers(providers); - sh_string = _getMembers(shippers); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = dropDummy(_buyers[0].members); + sellers = dropDummy(_sellers[0].members); + providers = dropDummy(_providers[0].members); + shippers = dropDummy(_shippers[0].members); + s_string = _getMembers(sellers); + p_string = _getMembers(providers); + sh_string = _getMembers(shippers); - }); + }); } /** * dropDummy() removes 'noop@dummy' from memberlist + * @param {String} _in - member id to ignore */ function dropDummy(_in) { - var _a = new Array() - for (each in _in){(function(_idx, _arr){console.log('_arr['+_idx+'].id is: '+_arr[_idx].id); if (_arr[_idx].id !== 'noop@dummy')_a.push(_arr[_idx]);})(each, _in)} - return _a; + let _a = new Array() + for (let each in _in){(function(_idx, _arr){console.log('_arr['+_idx+'].id is: '+_arr[_idx].id); if (_arr[_idx].id !== 'noop@dummy')_a.push(_arr[_idx]);})(each, _in);} + return _a; } /** * load all of the members in the network for use in the different user experiences. This routine is designed for use if the network has been newly deployed and the web app was @@ -91,47 +95,48 @@ function dropDummy(_in) */ function deferredMemberLoad() { - var d_prompts = $.Deferred(); - var options = {}; - options.registry = 'Seller'; - var options2 = {}; - options2.registry = 'Buyer'; - var options3 = {}; - options3.registry = 'Provider'; - var options4 = {}; - options4.registry = 'Shipper'; - $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), - $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) - { - buyers = dropDummy(_buyers[0].members); - sellers = dropDummy(_sellers[0].members); - providers = dropDummy(_providers[0].members); - shippers = dropDummy(_shippers[0].members); - s_string = _getMembers(sellers); - p_string = _getMembers(providers); - sh_string = _getMembers(shippers); - d_prompts.resolve(); - }).fail(d_prompts.reject); - return d_prompts.promise(); + let d_prompts = $.Deferred(); + let options = {}; + options.registry = 'Seller'; + let options2 = {}; + options2.registry = 'Buyer'; + let options3 = {}; + options3.registry = 'Provider'; + let options4 = {}; + options4.registry = 'Shipper'; + $.when($.post('/composer/admin/getMembers', options), $.post('/composer/admin/getMembers', options2), + $.post('/composer/admin/getMembers', options3), $.post('/composer/admin/getMembers', options4)).done(function (_sellers, _buyers, _providers, _shippers) + { + buyers = dropDummy(_buyers[0].members); + sellers = dropDummy(_sellers[0].members); + providers = dropDummy(_providers[0].members); + shippers = dropDummy(_shippers[0].members); + s_string = _getMembers(sellers); + p_string = _getMembers(providers); + sh_string = _getMembers(shippers); + d_prompts.resolve(); + }).fail(d_prompts.reject); + return d_prompts.promise(); } /** * return an option list for use in an HTML '; - return _str; + return _str; } /** * set up the server to listen for all events */ function goEventInitialize() { - $.when($.get('/composer/client/initEventRegistry')).done(function(_res){console.log(_res);}) + $.when($.get('/composer/client/initEventRegistry')).done(function(_res){console.log(_res);}) } /** @@ -139,175 +144,137 @@ function goEventInitialize() */ function getAlertPort () { - if (alertPort == null) - { - $.when($.get('/setup/getAlertPort')).done(function (port) + if (alertPort === null) { - console.log('alert port is: '+port.port); alertPort = port.port; - var wsSocket = new WebSocket('ws://localhost:'+alertPort); - wsSocket.onopen = function () {wsSocket.send('connected to alerts');}; - wsSocket.onmessage = function (message) { - console.log(message.data); - var event = JSON.parse(message.data); - // use the addNotification routine in this file to update the alert status for the relevant subscriber - /* - * YOUR CODE HERE - * - */ -}; - - wsSocket.onerror = function (error) {console.log('Alert Socket error on wsSocket: ' + error);}; + $.when($.get('/setup/getAlertPort')).done(function (port) + { + console.log('alert port is: '+port.port); alertPort = port.port; + let wsSocket = new WebSocket('ws://localhost:'+alertPort); + wsSocket.onopen = function () {wsSocket.send('connected to alerts');}; + wsSocket.onmessage = function (message) { + console.log(message.data); + let event = JSON.parse(message.data); + addNotification(event.type, event.ID, event.orderID); + }; + wsSocket.onerror = function (error) {console.log('Alert Socket error on wsSocket: ' + error);}; }); - } + } } /** * get the finance alert web socket port */ function getFinanceAlertPort () { - if (financeAlertPort == null) - { - $.when($.get('/setup/getFinanceAlertPort')).done(function (port) + if (financeAlertPort === null) { - console.log('finance alert port is: '+port.port); financeAlertPort = port.port; - var wsSocket = new WebSocket('ws://localhost:'+financeAlertPort); - wsSocket.onopen = function () {wsSocket.send('connected to finance alerts');}; - wsSocket.onmessage = function (message) { - console.log(message.data); - var event = JSON.parse(message.data); - // use the addNotification routine in this file to update the alert status for the relevant subscriber - /* - * YOUR CODE HERE - * - */ -}; - - wsSocket.onerror = function (error) {console.log('Finance Alert Socket error on wsSocket: ' + error);}; + $.when($.get('/setup/getFinanceAlertPort')).done(function (port) + { + console.log('finance alert port is: '+port.port); financeAlertPort = port.port; + let wsSocket = new WebSocket('ws://localhost:'+financeAlertPort); + wsSocket.onopen = function () {wsSocket.send('connected to finance alerts');}; + wsSocket.onmessage = function (message) { + console.log(message.data); + let event = JSON.parse(message.data); + addNotification(event.type, event.ID, event.orderID); + }; + wsSocket.onerror = function (error) {console.log('Finance Alert Socket error on wsSocket: ' + error);}; }); - } + } } + /** - * alert processing + * + * @param {Event} _event - inbound Event + * @param {String} _id - subscriber target + * @param {String} _orderID - inbound order id */ function addNotification(_event, _id, _orderID) { - // let's display each received event - var method = 'showNotification'; - console.log(method+' _event'+_event+' id: '+_id+' orderID: '+_orderID); - // using the getSubscriber routine, find the class of this event - /* - * YOUR CODE HERE - * - */ - // if no one of the specified type is listening, just return with a value of 'none' - if (type == 'none') {return} - // create a switch/case statement for each type of member - // update the x_alerts array with the new alert - // call the toggleAlert routine to update the alert icon - switch(type) - { + let method = 'showNotification'; + console.log(method+' _event'+_event+' id: '+_id+' orderID: '+_orderID); + let type = getSubscriber(_id); + if (type === 'none') {return;} + switch(type) + { case 'Buyer': - /* - * YOUR CODE HERE - * - */ - break; + b_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(b_notify, b_alerts, b_count); + break; case 'Seller': - /* - * YOUR CODE HERE - * - */ - break; + s_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(s_notify, s_alerts, s_count); + break; case 'Provider': - /* - * YOUR CODE HERE - * - */ - break; + p_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(p_notify, p_alerts, p_count); + break; case 'Shipper': - /* - * YOUR CODE HERE - * - */ - break; + sh_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(sh_notify, sh_alerts, sh_count); + break; case 'FinanceCo': - /* - * YOUR CODE HERE - * - */ - break; + f_alerts.push({'event': _event, 'order': _orderID}); + toggleAlert(f_notify, f_alerts, f_count); + break; default: - console.log(method+' default entered for: '+type); - break; - } + console.log(method+' default entered for: '+type); + break; + } } /** - * alert toggle + * + * @param {jQuery} _target - jquery object to update + * @param {Array} _array - array of alerts for this member + * @param {jQuery} _count - jQuery object to hold alert count */ function toggleAlert(_target, _array, _count) { - // if there aren't any elements in the array, then hide the alert icon - if (_array.length < 1) - /* - * YOUR CODE HERE - * - */ - // if the alert array has anything in it, then show the alert icon and update the count with the number of items in the alert array - /* - * YOUR CODE HERE - * - */ + if (_array.length < 1) + {$(_target).removeClass('on'); $(_target).addClass('off'); } + else {$(_count).empty(); $(_count).append(_array.length); + $(_target).removeClass('off'); $(_target).addClass('on'); } + } /** * check to see if _id is subscribing + * @param {Integer} _id - member id to seek + * @returns {String} - type of member */ function getSubscriber(_id) { - var type = 'none'; - // get the member type from the subscriber array. if the member is not not found, return 'none' - /* - * YOUR CODE HERE - * - */ - return(type); + let type = 'none'; + for (let each in subscribers){(function(_idx, _arr){if (_arr[_idx].id === _id){type=_arr[_idx].type;}})(each, subscribers);} + return(type); } /** * subscribe to events - * - * + * @param {String} _type - member type + * @param {String} _id - member id */ function z2bSubscribe(_type, _id) { - // update the subscriber array with the provided id and type. - subscribers.push({'type': _type, 'id': _id}); + subscribers.push({'type': _type, 'id': _id}); } /** - * unsubscribe to events - * - * + * Unsubscribe to events + * @param {String} _id - member id to remove */ function z2bUnSubscribe(_id) { - // remove the provided id from the member array. If the id is not found, the subscriber array is returned in the original state. - var _s1 = subscribers; - var _s2 = []; - /* - * YOUR CODE HERE - * - */ - subscribers = _s2; + let _s1 = subscribers; + let _s2 = []; + for (let each in _s1) {(function(_idx, _arr){if (_arr[_idx] != _id){_s2.push(_arr[_idx]);}})(each, _s1);} + subscribers = _s2; } /** * notifyMe + * @param {Array} _alerts - array of alerts * @param {String} _id - orderID + * @returns {Boolean} - true if found, false if not found */ function notifyMe (_alerts, _id) { - // check to see if the provided orderID is in the provided alert array. If so, return true, else return false. - var b_h = false; - /* - * YOUR CODE HERE - * - */ - return b_h; + let b_h = false; + for (let each in _alerts) {(function(_idx, _arr){if (_id === _arr[_idx].order){b_h = true;}})(each, _alerts);} + return b_h; } \ No newline at end of file diff --git a/Chapter12/HTML/js/z2b-financeCo.js b/Chapter12/HTML/js/z2b-financeCo.js index 3bb584e..703b3e2 100644 --- a/Chapter12/HTML/js/z2b-financeCo.js +++ b/Chapter12/HTML/js/z2b-financeCo.js @@ -14,211 +14,212 @@ // z2c-financeCo.js -var financeCOorderDiv = "financeCOorderDiv"; -var orders = []; +'use strict'; + +let financeCOorderDiv = 'financeCOorderDiv'; +let orders = []; const financeCoID = 'easymoney@easymoneyinc.com'; const financeCoName = 'The Global Financier'; -var f_notify = '#financeCo_notify'; -var f_id = 'easymoney@easymoneyinc.com'; -var f_count = '#financeCo_count'; -var f_alerts; - +let f_notify = '#financeCo_notify'; +let f_id = 'easymoney@easymoneyinc.com'; +let f_count = '#financeCo_count'; +let f_alerts; /** - * load the administration User Experience + * load the finance company User Experience */ function loadFinanceCoUX () { - toLoad = "financeCo.html"; - // get the FinanceAlert Port - /* - * YOUR CODE HERE - * - */ - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupFinanceCo(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupFinanceCo(page[0], port[0]);}); - } + let toLoad = 'financeCo.html'; + // get the FinanceAlert Port + getFinanceAlertPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) + {setupFinanceCo(page[0], port[0]);}); + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupFinanceCo(page[0], port[0]);}); + } } - +/** + * @param {String} page HTML page to load + * @param {Integer} port Websocket port to use + */ function setupFinanceCo(page, port) { - $("#body").empty(); - $("#body").append(page); - f_alerts = []; - if (f_alerts.length == 0) - {$(f_notify).removeClass('on'); $(f_notify).addClass('off'); } - else - {$(f_notify).removeClass('off'); $(f_notify).addClass('on'); } - updatePage("financeCo"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('finance_messages', msgPort); - var _clear = $("#financeCOclear"); - var _list = $("#financeCOorderStatus"); - var _orderDiv = $("#"+financeCOorderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listFinanceOrders()}); - //set the alerts file to an empty array and update the html class appropriately - /* - * YOUR CODE HERE - * - */ + $('#body').empty(); + $('#body').append(page); + f_alerts = []; + if (f_alerts.length === 0) + {$(f_notify).removeClass('on'); $(f_notify).addClass('off'); } + else + {$(f_notify).removeClass('off'); $(f_notify).addClass('on'); } + updatePage( 'financeCo'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('finance_messages', msgPort); + let _clear = $('#financeCOclear'); + let _list = $('#financeCOorderStatus'); + let _orderDiv = $('#'+financeCOorderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listFinanceOrders();}); + z2bSubscribe('FinanceCo', f_id); } /** - * lists all orders for the selected seller + * lists all orders for the selected financier */ function listFinanceOrders() { - var options = {}; - options.id = financeCoID; - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = financeCoID; + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#"+financeCOorderDiv).empty(); $("#"+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} - else{orders = _results.orders; formatFinanceOrders($("#"+financeCOorderDiv), orders)} - }); - }); + if (_results.orders.length < 1) {$('#'+financeCOorderDiv).empty(); $('#'+financeCOorderDiv).append(formatMessage('No orders for the financeCo: '+options.id));} + else{orders = _results.orders; formatFinanceOrders($('#'+financeCOorderDiv), orders);} + }); } + /** * used by the listOrders() function - * formats the orders for a buyer. Orders to be formatted are provided in the _orders array + * formats the orders for a financier. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Integer} _orders - array with order objects */ function formatFinanceOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let p_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a financier can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - break; + _date = _arr[_idx].delivered; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Created.code: - _date = _arr[_idx].created; - break; + _date = _arr[_idx].created; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Authorize.code: - _date = _arr[_idx].approved; - _action += '' - break; + _date = _arr[_idx].approved; + _action += ''; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - break; + _date = _arr[_idx].bought; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Refund.code: - _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; - break; + _date = _arr[_idx].orderRefunded + '
'+_arr[_idx].refund; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += '
'; - _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_arr[_idx].buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= formatDetail(_idx, _arr[_idx]); - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { - $("#f_order"+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#order"+_idx+"_b").on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); - $("#f_btn_"+_idx).on('click', function () + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'; + _str += ''+_action+''+_button+'
Order #StatusTotalBuyer: '+findMember(_arr[_idx].buyer,buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= formatDetail(_idx, _arr[_idx]); + })(each, _orders); + } + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) { - var options = {}; - options.action = $("#f_action"+_idx).find(":selected").text(); - options.orderNo = $("#f_order"+_idx).text(); - options.participant = financeCoID; - console.log(options); - $("#finance_messages").prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#finance_messages").prepend(formatMessage(_results.result)); - }); - }); - // using the notifyMe function in the events.js file, update the b_status+_idx HTML element appropriately - /* - * YOUR CODE HERE - * - */ - })(each, _orders) - } - f_alerts = new Array(); - toggleAlert($('#financeCo_notify'), f_alerts, f_alerts.length); + $('#f_order'+_idx).on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#order'+_idx+'_b').on('click', function(){accToggle('financeCOorderDiv','order'+_idx+'_b', 'order'+_idx+'_h');}); + $('#f_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#f_action'+_idx).find(':selected').text(); + options.orderNo = $('#f_order'+_idx).text(); + options.participant = financeCoID; + console.log(options); + $('#finance_messages').prepend(formatMessage('Processing '+options.action+' request for order number: '+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#finance_messages').prepend(formatMessage(_results.result)); + }); + }); + if (notifyMe(f_alerts, _arr[_idx].id)) {$("#f_status"+_idx).addClass('highlight'); } + })(each, _orders); + } + f_alerts = new Array(); + toggleAlert($('#financeCo_notify'), f_alerts, f_alerts.length); } /** * format the accordian with the details for this order + * @param {Integer} _cur - offset into order array + * @param {JSON} _order - JSON object with current order data + * @returns {String} - html string to append to browser page */ function formatDetail(_cur, _order) { - console.log('['+_cur+'] is ',_order); - var _out = '
'; - _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; - _out += ''; - _out += ''; - _out += (_order.cancelled === "") ? '' : ''; - _out += (_order.bought === "") ? '' : ''; - _out += (_order.ordered === "") ? '' : ''; - _out += (_order.dateBackordered === "") ? '' : ''; - _out += (_order.requestShipment === "") ? '' : ''; - _out += (_order.delivering === "") ? '' : ''; - _out += (_order.delivered === "") ? '' : ''; - _out += (_order.paymentRequested === "") ? '' : ''; - _out += (_order.disputeOpened === "") ? '' : ''; - if (_order.disputeResolved === "") - { - if (_order.disputeOpened === "") - {_out += '';} + console.log('['+_cur+'] is ',_order); + let _out = '
'; + _out += '

'+textPrompts.financeCoOrder.status+'\t'+JSON.parse(_order.status).text+'

'; + _out += '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
'; + _out += ''; + _out += (_order.cancelled === '') ? '' : ''; + _out += (_order.bought === '') ? '' : ''; + _out += (_order.ordered === '') ? '' : ''; + _out += (_order.dateBackordered === '') ? '' : ''; + _out += (_order.requestShipment === '') ? '' : ''; + _out += (_order.delivering === '') ? '' : ''; + _out += (_order.delivered === '') ? '' : ''; + _out += (_order.paymentRequested === '') ? '' : ''; + _out += (_order.disputeOpened === '') ? '' : ''; + if (_order.disputeResolved === '') + { + if (_order.disputeOpened === '') + {_out += '';} + else + {_out += '';} + } else - {_out += '';} - } - else - {_out +='';} - _out += (_order.orderRefunded === "") ? '' : ''; - _out += (_order.approved === "") ? '' : ''; - _out += (_order.paid === "") ? '
'+textPrompts.financeCoOrder.status+''+textPrompts.financeCoOrder.by+''+textPrompts.financeCoOrder.date+''+textPrompts.financeCoOrder.comments+'
Created'+_order.buyer+''+_order.created+'
'+textPrompts.financeCoOrder.cancelled+'?'+textPrompts.financeCoOrder.notCancel+'
'+textPrompts.financeCoOrder.cancelled+''+_order.buyer+''+_order.cancelled+'
'+textPrompts.financeCoOrder.purchased+''+textPrompts.financeCoOrder.noPurchase+'
'+textPrompts.financeCoOrder.purchased+''+_order.buyer+''+_order.bought+'
'+textPrompts.financeCoOrder.thirdParty+''+textPrompts.financeCoOrder.nothirdParty+'
'+textPrompts.financeCoOrder.thirdParty+''+_order.seller+''+_order.ordered+'
'+textPrompts.financeCoOrder.backordered+'?'+textPrompts.financeCoOrder.notBackordered+'
'+textPrompts.financeCoOrder.backordered+''+_order.provider+''+_order.dateBackordered+''+_order.backorder+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noRequestShip+'
'+textPrompts.financeCoOrder.shippingRequested+''+_order.provider+''+_order.requestShipment+'
'+textPrompts.financeCoOrder.shippingRequested+''+textPrompts.financeCoOrder.noDeliveryStart+'
'+textPrompts.financeCoOrder.shippingStarted+''+_order.shipper+''+_order.delivering+'
'+textPrompts.financeCoOrder.delivered+''+textPrompts.financeCoOrder.notDelivered+'
'+textPrompts.financeCoOrder.delivered+''+_order.shipper+''+_order.delivered+'
'+textPrompts.financeCoOrder.payRequested+''+textPrompts.financeCoOrder.noRequest+'
'+textPrompts.financeCoOrder.payRequested+''+_order.paymentRequested+'
'+textPrompts.financeCoOrder.disputed+''+textPrompts.financeCoOrder.noDispute+'
'+textPrompts.financeCoOrder.disputed+''+_order.buyer+''+_order.disputeOpened+''+_order.dispute+'
Dispute Resolvednot in dispute
Dispute ResolvedDispute is Unresolved
Dispute ResolvedDispute is Unresolved
Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'
Refund?(No Refund in Process)
Refund?'+_order.orderRefunded+''+_order.refund+'
Payment Approved(No Approval from Buyer)
Payment Approved'+_order.buyer+''+_order.approved+'
Paid(UnPaid)
' : 'Paid'+_order.financeCo+''+_order.paid+'
'; - return _out; + {_out +='Dispute Resolved'+_order.disputeResolved+''+_order.resolve+'';} + _out += (_order.orderRefunded === '') ? 'Refund?(No Refund in Process)' : 'Refund?'+_order.orderRefunded+''+_order.refund+''; + _out += (_order.approved === '') ? 'Payment Approved(No Approval from Buyer)' : 'Payment Approved'+_order.buyer+''+_order.approved+''; + _out += (_order.paid === '') ? 'Paid(UnPaid)
' : 'Paid'+_order.financeCo+''+_order.paid+'
'; + return _out; } diff --git a/Chapter12/HTML/js/z2b-initiate.js b/Chapter12/HTML/js/z2b-initiate.js index 80d6221..3fcfe09 100644 --- a/Chapter12/HTML/js/z2b-initiate.js +++ b/Chapter12/HTML/js/z2b-initiate.js @@ -13,50 +13,52 @@ */ // z2c-initiate.js -var connectionProfileName = "z2b-test-profile"; -var networkFile = "zerotoblockchain-network.bna" -var businessNetwork = "zerotoblockchain-network"; -var buyers = new Array(); -var sellers= new Array(); -var providers= new Array(); -var shippers= new Array(); +'use strict'; -var s_string, p_string, sh_string; -var msgPort = null; +let connectionProfileName = 'z2b-test-profile'; +let networkFile = 'zerotoblockchain-network.bna'; +let businessNetwork = 'zerotoblockchain-network'; -var orderStatus = { - Created: {code: 1, text: 'Order Created'}, - Bought: {code: 2, text: 'Order Purchased'}, - Cancelled: {code: 3, text: 'Order Cancelled'}, - Ordered: {code: 4, text: 'Order Submitted to Provider'}, - ShipRequest: {code: 5, text: 'Shipping Requested'}, - Delivered: {code: 6, text: 'Order Delivered'}, - Delivering: {code: 15, text: 'Order being Delivered'}, - Backordered: {code: 7, text: 'Order Backordered'}, - Dispute: {code: 8, text: 'Order Disputed'}, - Resolve: {code: 9, text: 'Order Dispute Resolved'}, - PayRequest: {code: 10, text: 'Payment Requested'}, - Authorize: {code: 11, text: 'Payment Approved'}, - Paid: {code: 14, text: 'Payment Processed'}, - Refund: {code: 12, text: 'Order Refund Requested'}, - Refunded: {code: 13, text: 'Order Refunded'} +let buyers = new Array(); +let sellers= new Array(); +let providers= new Array(); +let shippers= new Array(); + +let s_string, p_string, sh_string; + +let orderStatus = { + Created: {code: 1, text: 'Order Created'}, + Bought: {code: 2, text: 'Order Purchased'}, + Cancelled: {code: 3, text: 'Order Cancelled'}, + Ordered: {code: 4, text: 'Order Submitted to Provider'}, + ShipRequest: {code: 5, text: 'Shipping Requested'}, + Delivered: {code: 6, text: 'Order Delivered'}, + Delivering: {code: 15, text: 'Order being Delivered'}, + Backordered: {code: 7, text: 'Order Backordered'}, + Dispute: {code: 8, text: 'Order Disputed'}, + Resolve: {code: 9, text: 'Order Dispute Resolved'}, + PayRequest: {code: 10, text: 'Payment Requested'}, + Authorize: {code: 11, text: 'Payment Approved'}, + Paid: {code: 14, text: 'Payment Processed'}, + Refund: {code: 12, text: 'Order Refund Requested'}, + Refunded: {code: 13, text: 'Order Refunded'} }; /** * standard home page initialization routine * Refer to this by {@link initPage()}. */ - function initPage () +function initPage () { - // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English - goMultiLingual("US_English", "index"); - // singleUX loads the members already present in the network - memberLoad(); - // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring - getChainEvents(); - // get the asynch port - getPort(); - // get the Alert Port - getAlertPort(); + // goMultiLingual() establishes what languages are available for this web app, populates the header with available languages and sets the default language to US_English + goMultiLingual('US_English', 'index'); + // singleUX loads the members already present in the network + memberLoad(); + // goChainEvents creates a web socket connection with the server and initiates blockchain event monitoring + getChainEvents(); + // get the asynch port + getPort(); + // get the Alert Port + getAlertPort(); } diff --git a/Chapter12/HTML/js/z2b-provider.js b/Chapter12/HTML/js/z2b-provider.js index a11e53a..b849d89 100644 --- a/Chapter12/HTML/js/z2b-provider.js +++ b/Chapter12/HTML/js/z2b-provider.js @@ -14,174 +14,184 @@ // z2c-provider.js -var providerOrderDiv = "providerOrderDiv"; -var p_alerts = []; -var p_notify = '#provider_notify'; -var p_count = '#provider_count'; -var p_id; +'use strict'; + +let providerOrderDiv = 'providerOrderDiv'; +let p_alerts = []; +let p_notify = '#provider_notify'; +let p_count = '#provider_count'; +let p_id; /** - * load the administration User Experience + * load the Provider User Experience */ function loadProviderUX () { - toLoad = "provider.html"; + let toLoad = 'provider.html'; getPort(); - if (buyers.length === 0) + if (buyers.length === 0) { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupProvider(page[0], port[0]);}); } else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) - {setupProvider(page[0], port[0]);}); + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupProvider(page[0], port[0]);}); } - } - +} + +/** + * load the Provider User Experience + * @param {String} page - the name of the page to load + * @param {Integer} port - the port number to use + */ function setupProvider(page, port) { - $("#providerbody").empty(); - $("#providerbody").append(page); - if (p_alerts.length == 0) - {$(p_notify).removeClass('on'); $(p_notify).addClass('off'); } - else {$(p_notify).removeClass('off'); $(p_notify).addClass('on'); } - updatePage("provider"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('provider_messages', msgPort); - var _clear = $("#provider_clear"); - var _list = $("#providerOrderStatus"); - var _orderDiv = $("#"+providerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listProviderOrders()}); - $("#provider").empty(); - $("#provider").append(p_string); - $("#providerCompany").empty(); - $("#providerCompany").append(providers[0].companyName); - p_id = providers[0].id; - z2bSubscribe('Provider', p_id); - // create a function to execute when the user selects a different provider - $("#provider").on('change', function() { - $("#providerCompany").empty(); _orderDiv.empty(); $("#provider_messages").empty(); - $("#providerCompany").append(findMember($("#provider").find(":selected").val(),providers).companyName); - z2bUnSubscribe(p_id); - p_id = findMember($("#provider").find(":selected").text(),providers).id; + $('#providerbody').empty(); + $('#providerbody').append(page); + if (p_alerts.length === 0) + {$(p_notify).removeClass('on'); $(p_notify).addClass('off'); } + else {$(p_notify).removeClass('off'); $(p_notify).addClass('on'); } + updatePage('provider'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('provider_messages', msgPort); + let _clear = $('#provider_clear'); + let _list = $('#providerOrderStatus'); + let _orderDiv = $('#'+providerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listProviderOrders();}); + $('#provider').empty(); + $('#provider').append(p_string); + $('#providerCompany').empty(); + $('#providerCompany').append(providers[0].companyName); + p_id = providers[0].id; z2bSubscribe('Provider', p_id); -}); + // create a function to execute when the user selects a different provider + $('#provider').on('change', function() { + $('#providerCompany').empty(); _orderDiv.empty(); $('#provider_messages').empty(); + $('#providerCompany').append(findMember($('#provider').find(':selected').val(),providers).companyName); + z2bUnSubscribe(p_id); + p_id = findMember($('#provider').find(':selected').text(),providers).id; + z2bSubscribe('Provider', p_id); + }); } /** - * lists all orders for the selected seller + * lists all orders for the selected Provider */ function listProviderOrders() { - var options = {}; - options.id = $("#provider").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#provider').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#providerOrderDiv").empty(); $("#providerOrderDiv").append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} - else{formatProviderOrders($("#providerOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#providerOrderDiv').empty(); $('#providerOrderDiv').append(formatMessage(textPrompts.orderProcess.p_no_order_msg+options.id));} + else{formatProviderOrders($('#providerOrderDiv'), _results.orders);} + }); } + /** * used by the listOrders() function - * formats the orders for a buyer. Orders to be formatted are provided in the _orders array + * formats the orders for a Provider. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target * @param _target - string with div id prefaced by # * @param _orders - array with order objects */ function formatProviderOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; let b_string; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + b_string = ''; + // + // each order can have different states and the action that a Provider can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - _action += ''; - _action += ''; - b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; - break; + _date = _arr[_idx].ordered; + _action += ''; + _action += ''; + b_string = '
'+textPrompts.orderProcess.BackOrder.prompt+''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - _action += ''; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; - case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + b_string += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= ''; + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#p_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#p_action"+_idx).find(":selected").text(); - options.orderNo = $("#p_order"+_idx).text(); - options.participant = $("#provider").val(); - options.shipper = $("#shippers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund') || (options.action == 'BackOrder')) {options.reason = $("#p_reason"+_idx).val();} - console.log(options); - $("#provider_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#provider_messages").prepend(formatMessage(_results.result)); - }); - }); - if (notifyMe(_arr[_idx].id)) {$("#p_status"+_idx).addClass('highlight'); } - })(each, _orders) - } - p_alerts = new Array(); - toggleAlert($('#provider_notify'), p_alerts, p_alerts.length); + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#p_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#p_action'+_idx).find(':selected').text(); + options.orderNo = $('#p_order'+_idx).text(); + options.participant = $('#provider').val(); + options.shipper = $('#shippers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund') || (options.action === 'BackOrder')) {options.reason = $('#p_reason'+_idx).val();} + console.log(options); + $('#provider_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#provider_messages').prepend(formatMessage(_results.result)); + }); + }); + if (notifyMe(_arr[_idx].id)) {$('#p_status'+_idx).addClass('highlight'); } + })(each, _orders); + } + p_alerts = new Array(); + toggleAlert($('#provider_notify'), p_alerts, p_alerts.length); } \ No newline at end of file diff --git a/Chapter12/HTML/js/z2b-seller.js b/Chapter12/HTML/js/z2b-seller.js index c63b2ee..3a8fd29 100644 --- a/Chapter12/HTML/js/z2b-seller.js +++ b/Chapter12/HTML/js/z2b-seller.js @@ -13,167 +13,186 @@ */ // z2c-seller.js -var sellerOrderDiv = "sellerOrderDiv"; -var s_alerts = []; -var s_notify = '#seller_notify'; -var s_count = '#seller_count'; -var s_id; + +'use strict'; +let sellerOrderDiv = 'sellerOrderDiv'; +let s_alerts = []; +let s_notify = '#seller_notify'; +let s_count = '#seller_count'; +let s_id; /** - * load the administration User Experience + * load the administration Seller Experience */ function loadSellerUX () { - toLoad = "seller.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupSeller(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'seller.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupSeller(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupSeller(page[0], port[0]);}); + } } +/** + * load the administration User Experience + * @param {String} page - page to load + * @param {Integer} port - web socket port to use + */ function setupSeller(page, port) { - $("#sellerbody").empty(); - $("#sellerbody").append(page); - if (s_alerts.length == 0) - {$(s_notify).removeClass('on'); $(s_notify).addClass('off'); } - else {$(s_notify).removeClass('off'); $(s_notify).addClass('on'); } - updatePage("seller"); - msgPort = port.port; - wsDisplay('seller_messages', msgPort); - var _clear = $("#seller_clear"); - var _list = $("#sellerOrderStatus"); - var _orderDiv = $("#"+sellerOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listSellerOrders()}); - $("#seller").empty(); - $("#seller").append(s_string); - $("#sellerCompany").empty(); - $("#sellerCompany").append(sellers[0].companyName); - s_id = sellers[0].id; - z2bSubscribe('Seller', s_id); - // create a function to execute when the user selects a different provider - $("#seller").on('change', function() { - $("#sellerCompany").empty(); _orderDiv.empty(); $("#seller_messages").empty(); - $("#sellerCompany").append(findMember($("#seller").find(":selected").val(),sellers).companyName); - z2bUnSubscribe(s_id); - s_id = findMember($("#seller").find(":selected").text(),sellers).id; + $('#sellerbody').empty(); + $('#sellerbody').append(page); + if (s_alerts.length == 0) + {$(s_notify).removeClass('on'); $(s_notify).addClass('off'); } + else {$(s_notify).removeClass('off'); $(s_notify).addClass('on'); } + updatePage('seller'); + msgPort = port.port; + wsDisplay('seller_messages', msgPort); + let _clear = $('#seller_clear'); + let _list = $('#sellerOrderStatus'); + let _orderDiv = $('#'+sellerOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + // + // this section changes from the previous chapter, buyer changing to seller + // + _list.on('click', function(){listSellerOrders();}); + $('#seller').empty(); + $('#seller').append(s_string); + $('#sellerCompany').empty(); + $('#sellerCompany').append(sellers[0].companyName); + s_id = sellers[0].id; z2bSubscribe('Seller', s_id); - }); + // create a function to execute when the user selects a different provider + $('#seller').on('change', function() { + $('#sellerCompany').empty(); _orderDiv.empty(); $('#seller_messages').empty(); + $('#sellerCompany').append(findMember($('#seller').find(':selected').val(),sellers).companyName); + z2bUnSubscribe(s_id); + s_id = findMember($('#seller').find(':selected').text(),sellers).id; + z2bSubscribe('Seller', s_id); + }); } /** * lists all orders for the selected seller */ function listSellerOrders() { - var options = {}; - options.id = $("#seller").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + // + // seller instead of buyer + // + options.id= $('#seller').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { - if (_results.orders.length < 1) {$("#sellerOrderDiv").empty(); $("#sellerOrderDiv").append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} - else{formatSellerOrders($("#sellerOrderDiv"), _results.orders)} - }); - }); + { + if (_results.orders.length < 1) {$('#sellerOrderDiv').empty(); $('#sellerOrderDiv').append(formatMessage(textPrompts.orderProcess.s_no_order_msg+options.id));} + else{formatSellerOrders($('#sellerOrderDiv'), _results.orders);} + }); } /** * used by the listOrders() function * formats the orders for a buyer. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target - * @param _target - string with div id prefaced by # - * @param _orders - array with order objects + * @param {String} _target - string with div id prefaced by # + * @param {Array} _orders - array with order objects */ function formatSellerOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + // + // each order can have different states and the action that a buyer can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.PayRequest.code: - _date = _arr[_idx].paymentRequested; - break; + _date = _arr[_idx].paymentRequested; + break; case orderStatus.Bought.code: - _date = _arr[_idx].bought; - _action += ''; - break; + _date = _arr[_idx].bought; + _action += ''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _action += ''; - break; + _date = _arr[_idx].delivered; + _action += ''; + break; case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - break; + _date = _arr[_idx].requestShipment; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - break; + _date = _arr[_idx].delivering; + break; case orderStatus.Ordered.code: - _date = _arr[_idx].ordered; - break; + _date = _arr[_idx].ordered; + break; case orderStatus.Backordered.code: - _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; - break; + _date = _arr[_idx].dateBackordered + '
'+_arr[_idx].backorder; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - var _string = '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened + '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + let _string = '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - _action += ''; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + _action += ''; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - break; - } - _button = '' - _action += ""; - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + break; + } + let _button = '' + _action += ''; + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+''+textPrompts.orderProcess.buyer+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - - _target.append(_str); - for (let each in _orders) + + _target.append(_str); + for (let each in _orders) {(function(_idx, _arr) - { $("#s_btn_"+_idx).on('click', function () + { $('#s_btn_'+_idx).on('click', function () { - var options = {}; - options.action = $("#s_action"+_idx).find(":selected").text(); - options.orderNo = $("#s_order"+_idx).text(); - options.participant = $("#seller").val(); - options.provider = $("#providers"+_idx).find(":selected").val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#s_reason"+_idx).val();} - $("#seller_messages").prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); + let options = {}; + options.action = $('#s_action'+_idx).find(':selected').text(); + options.orderNo = $('#s_order'+_idx).text(); + options.participant = $('#seller').val(); + options.provider = $('#providers'+_idx).find(':selected').val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#s_reason'+_idx).val();} + $('#seller_messages').prepend(formatMessage(options.action+textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo)+options.orderNo)); $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { $("#seller_messages").prepend(formatMessage(_results.result)); }); + { $('#seller_messages').prepend(formatMessage(_results.result)); }); }); - if (notifyMe(s_alerts, _arr[_idx].id)) {$("#s_status"+_idx).addClass('highlight'); } - })(each, _orders) - } - s_alerts = new Array(); - toggleAlert($('#seller_notify'), s_alerts, s_alerts.length); + if (notifyMe(s_alerts, _arr[_idx].id)) {$('#s_status'+_idx).addClass('highlight'); } + })(each, _orders); + } + s_alerts = new Array(); + toggleAlert($('#seller_notify'), s_alerts, s_alerts.length); } \ No newline at end of file diff --git a/Chapter12/HTML/js/z2b-shipper.js b/Chapter12/HTML/js/z2b-shipper.js index 31ca734..9746eb1 100644 --- a/Chapter12/HTML/js/z2b-shipper.js +++ b/Chapter12/HTML/js/z2b-shipper.js @@ -14,168 +14,181 @@ // z2c-shipper.js -var shipperOrderDiv = "shipperOrderDiv"; -var sh_alerts = []; -var sh_notify = '#shipper_notify'; -var sh_count = '#shipper_count'; -var sh_id; +'use strict'; + +let shipperOrderDiv = 'shipperOrderDiv'; +let sh_alerts = []; +let sh_notify = '#shipper_notify'; +let sh_count = '#shipper_count'; +let sh_id; + /** - * load the administration User Experience + * load the shipper User Experience */ function loadShipperUX () { - toLoad = "shipper.html"; - getPort(); - if (buyers.length === 0) - { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) - {setupShipper(page[0], port[0]);}); -} - else{ - $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + let toLoad = 'shipper.html'; + getPort(); + if (buyers.length === 0) + { $.when($.get(toLoad), $.get('/setup/getPort'), deferredMemberLoad()).done(function (page, port, res) {setupShipper(page[0], port[0]);}); - } + } + else{ + $.when($.get(toLoad), $.get('/setup/getPort')).done(function (page, port) + {setupShipper(page[0], port[0]);}); + } } - +/** + * + * @param {String} page - the page to load + * @param {Integer} port - the web socket to use + */ function setupShipper(page, port) { - $("#shipperbody").empty(); - $("#shipperbody").append(page); - if (sh_alerts.length == 0) - {$(sh_notify).removeClass('on'); $(sh_notify).addClass('off'); } - else {$(sh_notify).removeClass('off'); $(sh_notify).addClass('on'); } - updatePage("shipper"); - console.log('port is: '+port.port); - msgPort = port.port; - wsDisplay('shipper_messages', msgPort); - var _clear = $("#shipper_clear"); - var _list = $("#shipperOrderStatus"); - var _orderDiv = $("#"+shipperOrderDiv); - _clear.on('click', function(){_orderDiv.empty();}); - _list.on('click', function(){listShipperOrders()}); - $("#shipper").empty(); - $("#shipper").append(sh_string); - $("#shipperCompany").empty(); - $("#shipperCompany").append(providers[0].companyName); - sh_id = shippers[0].id; - z2bSubscribe('Shipper', sh_id); - // create a function to execute when the user selects a different provider - $("#shipper").on('change', function() { - $("#shipperCompany").empty(); _orderDiv.empty(); $("#shipper_messages").empty(); - $("#shipperCompany").append(findMember($("#shipper").find(":selected").val(),shippers).companyName); - z2bUnSubscribe(sh_id); - sh_id = findMember($("#shipper").find(":selected").text(),shippers).id; + $('#shipperbody').empty(); + $('#shipperbody').append(page); + if (sh_alerts.length === 0) + {$(sh_notify).removeClass('on'); $(sh_notify).addClass('off'); } + else {$(sh_notify).removeClass('off'); $(sh_notify).addClass('on'); } + updatePage('shipper'); + console.log('port is: '+port.port); + msgPort = port.port; + wsDisplay('shipper_messages', msgPort); + let _clear = $('#shipper_clear'); + let _list = $('#shipperOrderStatus'); + let _orderDiv = $('#'+shipperOrderDiv); + _clear.on('click', function(){_orderDiv.empty();}); + _list.on('click', function(){listShipperOrders();}); + $('#shipper').empty(); + $('#shipper').append(sh_string); + $('#shipperCompany').empty(); + $('#shipperCompany').append(providers[0].companyName); + sh_id = shippers[0].id; z2bSubscribe('Shipper', sh_id); - }); + // create a function to execute when the user selects a different provider + $('#shipper').on('change', function() { + $('#shipperCompany').empty(); _orderDiv.empty(); $('#shipper_messages').empty(); + $('#shipperCompany').append(findMember($('#shipper').find(':selected').val(),shippers).companyName); + z2bUnSubscribe(sh_id); + sh_id = findMember($('#shipper').find(':selected').text(),shippers).id; + z2bSubscribe('Shipper', sh_id); + }); } /** - * lists all orders for the selected seller + * lists all orders for the selected shipper */ function listShipperOrders() { - var options = {}; - options.id = $("#shipper").find(":selected").val(); - $.when($.post('/composer/admin/getSecret', options)).done(function(_mem) - { - console.log(_mem); - options.userID = _mem.userID; options.secret = _mem.secret; + let options = {}; + options.id = $('#shipper').find(':selected').val(); + options.userID = options.id; $.when($.post('/composer/client/getMyOrders', options)).done(function(_results) - { + { console.log(_results.result); console.log(_results.orders); - if (_results.orders.length < 1) {$("#shipperOrderDiv").empty(); $("#shipperOrderDiv").append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} - else{formatShipperOrders($("#shipperOrderDiv"), _results.orders)} - }); - }); + if (_results.orders.length < 1) {$('#shipperOrderDiv').empty(); $('#shipperOrderDiv').append(formatMessage(textPrompts.orderProcess.sh_no_order_msg+options.id));} + else{formatShipperOrders($('#shipperOrderDiv'), _results.orders)} + }); } /** * used by the listOrders() function - * formats the orders for a buyer. Orders to be formatted are provided in the _orders array + * formats the orders for a shipper. Orders to be formatted are provided in the _orders array * output replaces the current contents of the html element identified by _target * @param _target - string with div id prefaced by # * @param _orders - array with order objects */ function formatShipperOrders(_target, _orders) { - _target.empty(); - let _str = ""; let _date = ""; var _statusText; - for (let each in _orders) - {(function(_idx, _arr) - { _action = ''; + _statusText = ''; + // + // each order can have different states and the action that a shipper can take is directly dependent on the state of the order. + // this switch/case table displays selected order information based on its current status and displays selected actions, which + // are limited by the sate of the order. + // + // Throughout this code, you will see many different objects referemced by 'textPrompts.orderProcess.(something)' + // These are the text strings which will be displayed in the browser and are retrieved from the prompts.json file + // associated with the language selected by the web user. + // + switch (JSON.parse(_arr[_idx].status).code) + { case orderStatus.ShipRequest.code: - _date = _arr[_idx].requestShipment; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].requestShipment; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivering.code: - _date = _arr[_idx].delivering; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivering; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Delivered.code: - _date = _arr[_idx].delivered; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - break; + _date = _arr[_idx].delivered; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + break; case orderStatus.Dispute.code: - _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; - _action += ''; - _action += ''; - _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; - _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; - break; + _date = _arr[_idx].disputeOpened+ '
'+_arr[_idx].dispute; + _action += ''; + _action += ''; + _statusText = '
'+textPrompts.orderProcess.Delivering.prompt+''; + _statusText += '
'+textPrompts.orderProcess.Refund.prompt+''; + break; case orderStatus.Resolve.code: - _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; - break; + _date = _arr[_idx].disputeResolved + '
'+_arr[_idx].resolve; + break; case orderStatus.Cancelled.code: - _date = _arr[_idx].cancelled; - break; + _date = _arr[_idx].cancelled; + break; case orderStatus.Paid.code: - _date = _arr[_idx].paid; - break; + _date = _arr[_idx].paid; + break; default: - console.log('OrderStatus not processed for: '+_arr[_idx].status); - break; - } - _button = '' - _action += ""; - console.log("shipper _action: "+_action); - if (_idx > 0) {_str += '
';} - _str += ''; - _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; - _str+= '' - for (let every in _arr[_idx].items) - {(function(_idx2, _arr2) - { let _item = JSON.parse(_arr2[_idx2]); - _str += ''; - })(every, _arr[_idx].items) + console.log('OrderStatus not processed for: '+_arr[_idx].status); + break; + } + let _button = ''; + _action += ''; + console.log('shipper _action: '+_action); + if (_idx > 0) {_str += '
';} + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + _str += ''+_action+_statusText+''+_button+'
'+textPrompts.orderProcess.orderno+''+textPrompts.orderProcess.status+''+textPrompts.orderProcess.total+'Buyer: '+findMember(_arr[_idx].buyer.split('#')[1],buyers).companyName+'
'+_arr[_idx].id+''+JSON.parse(_arr[_idx].status).text+': '+_date+'$'+_arr[_idx].amount+'.00
'; + _str+= '' + for (let every in _arr[_idx].items) + {(function(_idx2, _arr2) + { let _item = JSON.parse(_arr2[_idx2]); + _str += ''; + })(every, _arr[_idx].items); + } + console.log(_str); + _str += '
'+textPrompts.orderProcess.itemno+''+textPrompts.orderProcess.description+''+textPrompts.orderProcess.qty+''+textPrompts.orderProcess.price+'
'+_item.itemNo+''+_item.description+''+_item.quantity+'$'+_item.extendedPrice+'.00
'; + })(each, _orders); } - _str += ''; - })(each, _orders) - } - _target.append(_str); - for (let each in _orders) - {(function(_idx, _arr) - { $("#sh_btn_"+_idx).on('click', function () - { - var options = {}; - options.action = $("#sh_action"+_idx).find(":selected").text(); - options.orderNo = $("#sh_order"+_idx).text(); - options.participant = $("#shipper").val(); - options.delivery = $("#delivery"+_idx).val(); - if ((options.action == 'Resolve') || (options.action == 'Refund')) {options.reason = $("#sh_reason"+_idx).val();} - console.log(options); - $("#shipper_messages").prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); - $.when($.post('/composer/client/orderAction', options)).done(function (_results) - { console.log(_results); - $("#shipper_messages").prepend(formatMessage(_results.result)); - }); - }); - if (notifyMe(sh_alerts, _arr[_idx].id)) {$("#sh_status"+_idx).addClass('highlight'); } - })(each, _orders) - } - sh_alerts = new Array(); - toggleAlert($('#shipper_notify'), sh_alerts, sh_alerts.length); -} \ No newline at end of file + _target.append(_str); + for (let each in _orders) + {(function(_idx, _arr) + { $('#sh_btn_'+_idx).on('click', function () + { + let options = {}; + options.action = $('#sh_action'+_idx).find(':selected').text(); + options.orderNo = $('#sh_order'+_idx).text(); + options.participant = $('#shipper').val(); + options.delivery = $('#delivery'+_idx).val(); + if ((options.action === 'Resolve') || (options.action === 'Refund')) {options.reason = $('#sh_reason'+_idx).val();} + console.log(options); + $('#shipper_messages').prepend(formatMessage(textPrompts.orderProcess.processing_msg.format(options.action, options.orderNo))); + $.when($.post('/composer/client/orderAction', options)).done(function (_results) + { console.log(_results); + $('#shipper_messages').prepend(formatMessage(_results.result)); + }); + }); + if (notifyMe(sh_alerts, _arr[_idx].id)) {$("#sh_status"+_idx).addClass('highlight'); } + })(each, _orders); + } + sh_alerts = new Array(); + toggleAlert($('#shipper_notify'), sh_alerts, sh_alerts.length); + } \ No newline at end of file diff --git a/Chapter12/HTML/js/z2b-utilities.js b/Chapter12/HTML/js/z2b-utilities.js index e493c4a..6072ca2 100644 --- a/Chapter12/HTML/js/z2b-utilities.js +++ b/Chapter12/HTML/js/z2b-utilities.js @@ -6,69 +6,72 @@ * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, + * distributed under the License is distributed on an "AS IS' BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ -// z2c-utilities.js - +// z2c-utilities.js +'use strict'; /** * creates a set of utilities inside the named space: z2c * All utilities are accessed as z2c.functionName() * @namespace - z2c */ -languages = {}, // getSupportedLanguages -selectedLanguage = {}, -language = "", -textLocations = {}, // getTextLocations -textPrompts = {}, // getSelectedPromots -subscribers = new Array(); // subscribers to business events +let languages = {}, // getSupportedLanguages + selectedLanguage = {}, + language = '', + textLocations = {}, // getTextLocations + textPrompts = {}, // getSelectedPromots + subscribers = new Array(); // subscribers to business events /** * get the value associated with a cookie named in the input * Refer to this by {@link getCookieValue}. * @param {String} _name - the name of the cookie to find -* @namespace +* @returns {String} - cookie value +* @namespace */ function getCookieValue(_name) { - var name = _name+"="; - var cookie_array= document.cookie.split(";"); - for (each in cookie_array) - { var c = cookie_array[each].trim(); - if(c.indexOf(name) == 0) return(c.substring(name.length, c.length)); - } - return(""); + let name = _name+'='; + let cookie_array= document.cookie.split(';'); + for (let each in cookie_array) + { + let c = cookie_array[each].trim(); + if(c.indexOf(name) === 0) {return(c.substring(name.length, c.length));} + } + return(''); } /** * trims a string by removing all leading and trailing spaces * trims the final period, if it exists, from a string. * Refer to this by {@link trimStrip}. -* @param {String} _string String to be trimmed and stripped of trailing period -* @namespace +* @param {String} _string - String to be trimmed and stripped of trailing period +* @returns {String} - trimmed string +* @namespace */ function trimStrip(_string) { - var str = _string.trim(); - var len = str.length; - if(str.endsWith(".")) {str=str.substring(0,len-1);} - return(str); + let str = _string.trim(); + let len = str.length; + if(str.endsWith('.')) {str=str.substring(0,len-1);} + return(str); } /** * replaces text on an html page based on the anchors and text provided in a JSON textPrompts object * Refer to this by {@link updatePage}. * @param {String} _page - a string representing the name of the html page to be updated -* @namespace +* @namespace */ function updatePage(_page) { - for (each in textPrompts[_page]){(function(_idx, _array) - {$("#"+_idx).empty();$("#"+_idx).append(getDisplaytext(_page, _idx));})(each, textPrompts[_page])} + for (let each in textPrompts[_page]){(function(_idx, _array) + {$('#'+_idx).empty();$('#'+_idx).append(getDisplaytext(_page, _idx));})(each, textPrompts[_page])} } /** @@ -76,7 +79,8 @@ function updatePage(_page) * Refer to this by {@link getDisplaytext}. * @param {String} _page - string representing the name of the html page to be updated * @param {String} _item - string representing the html named item to be updated -* @namespace +* @returns {String} - text to be placed on web page +* @namespace */ function getDisplaytext(_page, _item) {return (textPrompts[_page][_item]);} @@ -86,54 +90,56 @@ function getDisplaytext(_page, _item) * Refer to this by {@link goMultiLingual}. * @param {String} _language - language to be used in this session * @param {String} _page - string representing html page to be updated in the selected language -* @namespace +* @namespace */ function goMultiLingual(_language, _page) { language = _language; - $.when($.get("/api/getSupportedLanguages")).done(function(_res) - {languages = _res; - selectedLanguage = languages[_language]; - var options = {}; options.language = _language; - $.when($.get('/api/getTextLocations'),$.post('/api/selectedPrompts', options)).done(function(_locations, _prompts) - {textLocations = _locations; - textPrompts = JSON.parse(_prompts[0]); - updatePage(_page); + $.when($.get('/api/getSupportedLanguages')).done(function(_res) + {languages = _res; + selectedLanguage = languages[_language]; + let options = {}; options.language = _language; + $.when($.get('/api/getTextLocations'),$.post('/api/selectedPrompts', options)).done(function(_locations, _prompts) + {textLocations = _locations; + textPrompts = JSON.parse(_prompts[0]); + updatePage(_page); + }); + let _choices = $('#lang_choices'); + _choices.empty(); let _str = ''; + for (let each in _res) + {(function(_idx, _array) + {if (_array[_idx].active === 'yes') + {_str += '
  • '+_array[_idx].menu+'
  • '} + })(each, _res); + } + _choices.append(_str); }); - var _choices = $("#lang_choices"); - _choices.empty(); var _str = ""; - for (each in _res) - {(function(_idx, _array) - {if (_array[_idx].active == "yes") - {_str += '
  • '+_array[_idx].menu+'
  • '} - })(each, _res)} - _choices.append(_str); - }); } /** * get SupportedLanguages returns an html menu object with available languages * Refer to this by {@link getSupportedLanguages}. -* @namespace +* @namespace */ function getSupportedLanguages() { - $.when($.get("/api/getSupportedLanguages")).done(function(_res) - { - languages = _res; console.log(_res); var _choices = $("#lang_choices"); - _choices.empty(); var _str = ""; - for (each in _res) - {(function(_idx, _array) - {if (_array[_idx].active == "yes") - {_str += '
  • '+_array[_idx].menu+'
  • '} - })(each, _res)} - _choices.append(_str); - }); + $.when($.get('/api/getSupportedLanguages')).done(function(_res) + { + languages = _res; console.log(_res); let _choices = $('#lang_choices'); + _choices.empty(); let _str = ''; + for (let each in _res) + {(function(_idx, _array) + {if (_array[_idx].active === 'yes') + {_str += '
  • '+_array[_idx].menu+'
  • ';} + })(each, _res); + } + _choices.append(_str); + }); } /** * returns a JSON object with the pages and objects which support text replacement * Refer to this by {@link getTextLocations}. -* @namespace +* @namespace */ function getTextLocationsfunction () {$.when($.get('/api/getTextLocations')).done(function(_res){textLocations = _res; console.log(_res); });} @@ -141,38 +147,39 @@ function getTextLocationsfunction () /** * returns a JSON object with the text to be used to update identified pages and objects * Refer to this by {@link getSelectedPrompts}. -* @param {String} _inbound -* @namespace +* @param {String} _inbound - page or object to receive updated text +* @namespace */ function getSelectedPrompts(_inbound) { selectedLanguage=languages[_inbound]; - var options = {}; options.language = _inbound; - $.when($.post('/api/selectedPrompts', options)).done(function(_res){textPrompts = _res; console.log(_res); }); + let options = {}; options.language = _inbound; + $.when($.post('/api/selectedPrompts', options)).done(function(_res){textPrompts = _res; console.log(_res); }); } /** * retrieves the prompts for the requested language from the server * Refer to this by {@link qOnSelectedPrompts}. * @param {String} _inbound - string representing the requested language -* @namespace +* @returns {Promise} - returns promise when selected prompts have been retrieved from server +* @namespace */ function qOnSelectedPrompts(_inbound) { - var d_prompts = $.Deferred(); - var options = {}; options.language = _inbound; - $.when($.post('/api/selectedPrompts', options)).done(function (p) {d_prompts.resolve(p);}).fail(d_prompts.reject); - return d_prompts.promise(); + let d_prompts = $.Deferred(); + let options = {}; options.language = _inbound; + $.when($.post('/api/selectedPrompts', options)).done(function (p) {d_prompts.resolve(p);}).fail(d_prompts.reject); + return d_prompts.promise(); } /** * function to display the properties of an object using console.log * Refer to this by {@link displayObjectProperties}. * @param {Object} _obj - the object whose properties are to be displayed -* @namespace +* @namespace */ function displayObjectProperties(_obj) { - for(var propt in _obj){ console.log("object property: "+propt ); } + for(let propt in _obj){ console.log('object property: '+propt ); } } /** @@ -180,12 +187,12 @@ function displayObjectProperties(_obj) * Refer to this by {@link displayObjectValues}. * @param {String} _string - an arbitrary string to preface the printing of the object property name and value. often used to display the name of the object being printed * @param {Object} _object - the object to be introspected -* @namespace +* @namespace */ function displayObjectValues(_string, _object) { - for (prop in _object){ - console.log(_string+prop+": "+(((typeof(_object[prop]) == 'object') || (typeof(_object[prop]) == 'function')) ? typeof(_object[prop]) : _object[prop])); + for (let prop in _object){ + console.log(_string+prop+': '+(((typeof(_object[prop]) === 'object') || (typeof(_object[prop]) === 'function')) ? typeof(_object[prop]) : _object[prop])); } } @@ -202,82 +209,86 @@ function displayObjectValues(_string, _object) */ String.prototype.format = function(i, safe, arg) { +/** + * the format function added to String.prototype + * @returns {String} - returns original string with {x} replaced by provided text + */ + function format() { + let str = this, len = arguments.length+1; - function format() { - var str = this, len = arguments.length+1; - - // For each {0} {1} {n...} replace with the argument in that position. If - // the argument is an object or an array it will be stringified to JSON. - for (i=0; i < len; arg = arguments[i++]) { - safe = typeof arg === 'object' ? JSON.stringify(arg) : arg; - str = str.replace(RegExp('\\{'+(i-1)+'\\}', 'g'), safe); + // For each {0} {1} {n...} replace with the argument in that position. If + // the argument is an object or an array it will be stringified to JSON. + for (i=0; i < len; arg = arguments[i++]) { + safe = typeof arg === 'object' ? JSON.stringify(arg) : arg; + str = str.replace(RegExp('\\{'+(i-1)+'\\}', 'g'), safe); + } + return str; } - return str; - } - // Save a reference of what may already exist under the property native. - // Allows for doing something like: if("".format.native) { /* use native */ } - format.native = String.prototype.format; - - // Replace the prototype property - return format; + // Save a reference of what may already exist under the property native. + // Allows for doing something like: if(''.format.native) { /* use native */ } + format.native = String.prototype.format; + // Replace the prototype property + return format; }(); /** * display the hyperledger apis as currently understood * Refer to this by {@link showAPIDocs}. - * + * */ function showAPIDocs() { - $.when($.get('/resources/getDocs'),$.get('hfcAPI.html')).done(function(_res, _page) - { - var _target = $("#body"); - _target.empty(); _target.append(_page[0]); - displayAPI(_res[0]); - }); + $.when($.get('/resources/getDocs'),$.get('hfcAPI.html')).done(function(_res, _page) + { + let _target = $('#body'); + _target.empty(); _target.append(_page[0]); + displayAPI(_res[0]); + }); } /** - * - * @param {JSON} _api + * + * @param {JSON} _api * Refer to this by {@link displayAPI}. - * + * */ function displayAPI(_api) { - var _exports = _api.hfcExports; - var _classes = _api.hfcClasses; - var _eTarget = $("#hfc_exports"); - var _cTarget = $("#hfc_classes"); - var _str = ""; - for (each in _exports) { - (function(_idx, _arr){ - _curObj = Object.getOwnPropertyNames(_arr[_idx]); - _str += ""+_curObj+""+_arr[_idx][_curObj]+""; - })(each, _exports); - } - _eTarget.append(_str); - _str = ""; - for (each in _classes) { - (function(_idx, _arr){ - _curObj = Object.getOwnPropertyNames(_arr[_idx]); - for (every in _arr[_idx][_curObj[0]]){ - (function(_idx2, _arr2) - { - _curObj2 = Object.getOwnPropertyNames(_arr2[_idx2]); - _str+= ""+_curObj[0]+""+_curObj2+""+_arr2[_idx2][_curObj2[0]]+""; - })(every, _arr[_idx][_curObj[0]]) - } - })(each, _classes); - } - _cTarget.append(_str); + let _exports = _api.hfcExports; + let _classes = _api.hfcClasses; + let _eTarget = $('#hfc_exports'); + let _cTarget = $('#hfc_classes'); + let _str = ''; + for (let each in _exports) { + (function(_idx, _arr){ + let _curObj = Object.getOwnPropertyNames(_arr[_idx]); + _str += ''+_curObj+''+_arr[_idx][_curObj]+''; + })(each, _exports); + } + _eTarget.append(_str); + _str = ''; + for (let each in _classes) { + (function(_idx, _arr){ + let _curObj = Object.getOwnPropertyNames(_arr[_idx]); + for (let every in _arr[_idx][_curObj[0]]){ + (function(_idx2, _arr2) + { + let _curObj2 = Object.getOwnPropertyNames(_arr2[_idx2]); + _str+= ''+_curObj[0]+''+_curObj2+''+_arr2[_idx2][_curObj2[0]]+''; + })(every, _arr[_idx][_curObj[0]]); + } + })(each, _classes); + } + _cTarget.append(_str); } /** * format messages for display + * @param {String} _msg - text to be enclosed in html message format + * @returns {String} - html formatted message */ function formatMessage(_msg) {return '

    '+_msg+'

    ';} @@ -286,41 +297,47 @@ function formatMessage(_msg) {return '

    '+_msg+'

    ';} */ function getPort () { - if (msgPort == null) - { $.when($.get('/setup/getPort')).done(function (port){console.log('port is: '+port.port); msgPort = port.port;});} + if (msgPort === null) + { $.when($.get('/setup/getPort')).done(function (port){console.log('port is: '+port.port); msgPort = port.port;});} } + /** - * toggle an accordian window + * closes all accordians in this div + * @param {String} target - formatted jQuery string pointing to div with all accordians to collapse */ -function accToggle(_parent, _body, _header) +function accOff(target) { - var parent = "#"+_parent; - var body="#"+_body; - var header = _header; - if ($(body).hasClass("on")) - {$(body).removeClass("on"); $(body).addClass("off"); - $(parent).removeClass("on"); $(parent).addClass("off"); - }else - { - accOff(parent); - $(body).removeClass("off"); $(body).addClass("on"); - $(parent).removeClass("off"); $(parent).addClass("on"); - } + let thisElement = $(target); + let childNodes = thisElement.children(); + for (let each in childNodes) + {let node = '#'+childNodes[each].id; + if (node !== '#') + { + if($(node).hasClass('on')) {$(node).removeClass('on');} + $(node).addClass('off'); + } + } } + /** - * + * toggle an accordian window + * @param {String} _parent - Div holding all accordians + * @param {String} _body - Div which only appears when accordian is expanded + * @param {HTMLDiv} _header - Div which appears when accordian is collapsed */ -function accOff(target) +function accToggle(_parent, _body, _header) { - var thisElement = $(target); - var childNodes = thisElement.children(); - for (each in childNodes) - {var node = "#"+childNodes[each].id; - if (node != '#') - { - if($(node).hasClass("on")) {$(node).removeClass("on");} - $(node).addClass("off"); - } - } + let parent = '#'+_parent; + let body='#'+_body; + if ($(body).hasClass('on')) + { + $(body).removeClass('on'); $(body).addClass('off'); + $(parent).removeClass('on'); $(parent).addClass('off'); + }else + { + accOff(parent); + $(body).removeClass('off'); $(body).addClass('on'); + $(parent).removeClass('off'); $(parent).addClass('on'); + } } diff --git a/Chapter12/HTML/removeMember.html b/Chapter12/HTML/removeMember.html index 718b809..63adcf5 100644 --- a/Chapter12/HTML/removeMember.html +++ b/Chapter12/HTML/removeMember.html @@ -5,7 +5,7 @@ - +
    diff --git a/Chapter12/buildAndDeploy b/Chapter12/buildAndDeploy index fad9c34..83c72bb 100755 --- a/Chapter12/buildAndDeploy +++ b/Chapter12/buildAndDeploy @@ -51,6 +51,4 @@ showStep "creating archive" showStep "starting network" ./startup.sh showStep "deploying network" -./deployNetwork.sh -n $NETWORK_NAME -showStep "copying credentials" -cp controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457-priv ~/.hfc-key-store \ No newline at end of file +./deployNetwork.sh -n $NETWORK_NAME \ No newline at end of file diff --git a/Chapter12/controller/env.json b/Chapter12/controller/env.json index 0afea4b..dd1c45d 100644 --- a/Chapter12/controller/env.json +++ b/Chapter12/controller/env.json @@ -7,7 +7,9 @@ "adminPW": "adminpw", "PeerAdmin": "PeerAdmin", "PeerPW": "randomString", - "NS": "org.acme.Z2BTestNetwork" + "NS": "org.acme.Z2BTestNetwork", + "adminCard": "admin@zerotoblockchain-network", + "PeerCard": "PeerAdmin@hlfv1" }, "fabric": { @@ -21,5 +23,24 @@ "peerEventURL": "grpc://localhost:7053", "ordererURL" : "grpc://localhost:7050", "caURL": "http://localhost:7054" + }, + "metaData": + { "version": 1, + "userName": "temp", + "roles": [ ], + "businessNetwork":"", + "enrollmentSecret": "temp" + }, + "connectionProfile": + { + "name": "hlfv1", + "type": "hlfv1", + "orderers": [ { "url": "grpc://localhost:7050" } ], + "ca": { "url": "http://localhost:7054", "name": "ca.org1.example.com" }, + "peers": [ { "requestURL": "grpc://localhost:7051", "eventURL": "grpc://localhost:7053" } ], + "keyValStore": "/.composer-credentials", + "channel": "composerchannel", + "mspID": "Org1MSP", + "timeout": 300 } } \ No newline at end of file diff --git a/Chapter12/controller/restapi/features/composer/autoLoad.js b/Chapter12/controller/restapi/features/composer/autoLoad.js index dc905ad..69dab55 100644 --- a/Chapter12/controller/restapi/features/composer/autoLoad.js +++ b/Chapter12/controller/restapi/features/composer/autoLoad.js @@ -14,92 +14,87 @@ /** * This file is used to automatically populate the network with Order assets and members - * The opening section loads node modules required for this set of nodejs services - * to work. Most of these are from the hyperledger composer SDK. This module also + * The opening section loads node modules required for this set of nodejs services + * to work. Most of these are from the hyperledger composer SDK. This module also * uses services created specifically for this tutorial, in the Z2B_Services.js - * and Z2B_Utilities.js modules. + * and Z2B_Utilities.js modules. */ 'use strict'; -const BrowserFS = require('browserfs/dist/node/index'); -const network = 'zerotoblockchain-network'; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; -const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const financeCoID = 'easymoney@easymoneyinc.com'; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const config = require('../../../env.json'); -const NS = 'org.acme.Z2BTestNetwork'; /** - * itemTable and memberTable are used by the server to reduce load time requests + * itemTable and memberTable are used by the server to reduce load time requests * for member secrets and item information */ let itemTable = new Array(); let memberTable = new Array(); -let orderStatus = svc.orderStatus; +let socketAddr; + + -let connection; let socketAddr; /** - * getPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getPort = function(req, res, next) { let _conn = svc.createMessageSocket(); res.send({'port': _conn.socket}); -} +}; /** - * getAlertPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getAlertPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getAlertPort = function(req, res, next) { let _conn = svc.createAlertSocket(); res.send({'port': _conn.socket}); -} +}; /** - * getFinanceAlertPort is used to return the port number for socket interactions so that - * the browser can receive asynchronous notifications of work in process. - * This helps the user understand the current status of the auto load process. + * getFinanceAlertPort is used to return the port number for socket interactions so that + * the browser can receive asynchronous notifications of work in process. + * This helps the user understand the current status of the auto load process. * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * + * * @function */ exports.getFinanceAlertPort = function(req, res, next) { let _conn = svc.createFinanceAlertSocket(); res.send({'port': _conn.socket}); -} +}; /** - * autoLoad reads the memberList.json file from the Startup folder and adds members, + * autoLoad reads the memberList.json file from the Startup folder and adds members, * executes the identity process, and then loads orders - * + * * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client @@ -114,131 +109,155 @@ exports.autoLoad = function(req, res, next) { let businessNetworkConnection; let factory; let participant; svc.createMessageSocket(); - connection = svc.m_connection; socketAddr = svc.m_socketAddr; let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(() => { + // a businessNetworkConnection is required to add members + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // a businessNetworkConnection is required to add members - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, network, config.composer.adminID, config.composer.adminPW) - .then(() => { - // a factory is required to build the member object - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - //iterate through the list of members in the memberList.json file and - // first add the member to the network, then create an identity for - // them. This generates the memberList.txt file later used for - // retrieving member secrets. - for (let each in startupFile.members) - {(function(_idx, _arr) - { - // the participant registry is where member information is first stored - // there are individual registries for each type of participant, or member. - // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo - return businessNetworkConnection.getParticipantRegistry(NS+'.'+_arr[_idx].type) - .then(function(participantRegistry){ - return participantRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - participant = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - participant.companyName = _arr[_idx].companyName; - participantRegistry.add(participant) - .then(() => { - console.log('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+" successfully added"); - }) - .then(() => { - // an identity is required before a member can take action in the network. - return businessNetworkConnection.issueIdentity(NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) - .then((result) => { - let _mem = _arr[_idx]; - _mem.secret = result.userSecret; - _mem.userID = result.userID; - memberTable.push(_mem); - svc.saveMemberTable(memberTable); - }) - .catch((error) => { - console.error('create id for '+_arr[_idx].id+'failed.',error.message); - }); - }) - .catch((error) => {console.log(_arr[_idx].companyName+" add failed",error.message);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.members) - } - // iterate through the order objects in the memberList.json file. - for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items)} - svc.saveItemTable(itemTable); - for (let each in startupFile.assets) - {(function(_idx, _arr) - { - // each type of asset, like each member, gets it's own registry. Our application - // has only one type of asset: "Order" - return businessNetworkConnection.getAssetRegistry(NS+'.'+_arr[_idx].type) - .then((assetRegistry) => { - return assetRegistry.get(_arr[_idx].id) - .then((_res) => { - console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+NS+'.'+_arr[_idx].type); - }) - .catch((error) => { - // first, an Order Object is created - let order = factory.newResource(NS, _arr[_idx].type, _arr[_idx].id); - order = svc.createOrderTemplate(order); - let _tmp = svc.addItems(_arr[_idx], itemTable); - order.items = _tmp.items; - order.amount = _tmp.amount; - order.orderNumber = _arr[_idx].id; - // then the buy transaction is created - const createNew = factory.newTransaction(NS, 'CreateOrder'); - order.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - order.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', _arr[_idx].buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', _arr[_idx].seller); - createNew.amount = order.amount; - // then the order is added to the asset registry. - return assetRegistry.add(order) - .then(() => { - // then a createOrder transaction is processed which uses the chaincode - // establish the order with it's initial transaction state. - svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); - }) + // a factory is required to build the member object + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + //iterate through the list of members in the memberList.json file and + // first add the member to the network, then create an identity for + // them. This generates the memberList.txt file later used for + // retrieving member secrets. + for (let each in startupFile.members) + {(function(_idx, _arr) + { + // the participant registry is where member information is first stored + // there are individual registries for each type of participant, or member. + // In our case, that is Buyer, Seller, Provider, Shipper, FinanceCo + return businessNetworkConnection.getParticipantRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then(function(participantRegistry){ + return participantRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] member with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + participant = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + participant.companyName = _arr[_idx].companyName; + participantRegistry.add(participant) + .then(() => { + console.log('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + svc.m_connection.sendUTF('['+_idx+'] '+_arr[_idx].companyName+' successfully added'); + }) + .then(() => { + // an identity is required before a member can take action in the network. + // V0.14 + // return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].pw) + // V0.15 + console.log('issuing identity for: '+config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+_arr[_idx].type+'#'+_arr[_idx].id, _arr[_idx].id) + .then((result) => { + console.log('_arr[_idx].id: '+_arr[_idx].id); + console.log('result.userID: '+result.userID); + let _mem = _arr[_idx]; + _mem.secret = result.userSecret; + _mem.userID = result.userID; + memberTable.push(_mem); + // svc.saveMemberTable(memberTable); + let _meta = {}; + for (each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = result.userID; + _meta.enrollmentSecret = result.userSecret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + return adminConnection.importCard(result.userID, tempCard) + .then ((_res) => { if (_res) {console.log('card updated');} else {console.log('card imported');} }) .catch((error) => { - // in the development environment, because of how timing is set up, it is normal to - // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a - // logical transaction error. - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log("AL: "+_arr[_idx].id+" retrying assetRegistry.add for: "+_arr[_idx].id); - svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); - } - else {console.log('error with assetRegistry.add', error.message)} + console.error('adminConnection.importCard failed. ',error.message); }); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error.message)}); - })(each, startupFile.assets) - } + }) + .catch((error) => { + console.error('create id for '+_arr[_idx].id+'failed. ',error.message); + }); + }) + .catch((error) => {console.log(_arr[_idx].companyName+' add failed',error.message);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.members); + } + // iterate through the order objects in the memberList.json file. + for (let each in startupFile.items){(function(_idx, _arr){itemTable.push(_arr[_idx]);})(each, startupFile.items);} + svc.saveItemTable(itemTable); + for (let each in startupFile.assets) + {(function(_idx, _arr) + { + // each type of asset, like each member, gets it's own registry. Our application + // has only one type of asset: 'Order' + return businessNetworkConnection.getAssetRegistry(config.composer.NS+'.'+_arr[_idx].type) + .then((assetRegistry) => { + return assetRegistry.get(_arr[_idx].id) + .then((_res) => { + console.log('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + svc.m_connection.sendUTF('['+_idx+'] order with id: '+_arr[_idx].id+' already exists in Registry '+config.composer.NS+'.'+_arr[_idx].type); + }) + .catch((error) => { + // first, an Order Object is created + let order = factory.newResource(config.composer.NS, _arr[_idx].type, _arr[_idx].id); + order = svc.createOrderTemplate(order); + let _tmp = svc.addItems(_arr[_idx], itemTable); + order.items = _tmp.items; + order.amount = _tmp.amount; + order.orderNumber = _arr[_idx].id; + // then the buy transaction is created + const createNew = factory.newTransaction(config.composer.NS, 'CreateOrder'); + order.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + order.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + order.provider = factory.newRelationship(config.composer.NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(config.composer.NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.financeCo = factory.newRelationship(config.composer.NS, 'FinanceCo', financeCoID); + createNew.order = factory.newRelationship(config.composer.NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(config.composer.NS, 'Buyer', _arr[_idx].buyer); + createNew.seller = factory.newRelationship(config.composer.NS, 'Seller', _arr[_idx].seller); + createNew.amount = order.amount; + // then the order is added to the asset registry. + return assetRegistry.add(order) + .then(() => { + // then a createOrder transaction is processed which uses the chaincode + // establish the order with it's initial transaction state. + svc.loadTransaction(svc.m_connection, createNew, order.orderNumber, businessNetworkConnection); + }) + .catch((error) => { + // in the development environment, because of how timing is set up, it is normal to + // encounter the MVCC_READ_CONFLICT error. This is a database timing error, not a + // logical transaction error. + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log('AL: '+_arr[_idx].id+' retrying assetRegistry.add for: '+_arr[_idx].id); + svc.addOrder(svc.m_connection, order, assetRegistry, createNew, businessNetworkConnection); + } + else {console.log('error with assetRegistry.add', error.message);} + }); + }); }) - .catch((error) => {console.log('error with business network Connect', error.message)}); + .catch((error) => {console.log('error with getParticipantRegistry', error.message);}); + })(each, startupFile.assets); + } }) - .catch((error) => {console.log('error with adminConnect', error.message)}); - res.send({'port': socketAddr}); -} + .catch((error) => {console.log('error with business network Connect', error.message);}); + }) + .catch((error) => {console.log('error with adminConnect', error.message);}); + res.send({'port': socketAddr}); +}; /** * get member secret from member table. In normal production, the use would be responsible * for knowing their member secret. Because this is a demo, we're managing that informaiton * on the server and this routine gets that information for us so that we can successfully - * execute transactions. + * execute transactions. * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the member to find * @param {express.res} res - the outbound response object for communicating back to client @@ -250,8 +269,8 @@ exports.getMemberSecret = function(req, res, next) { let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); let _table = JSON.parse(fs.readFileSync(newFile)); - let bFound = false; + let bFound = false; for (let each in _table.members) - { if (_table.members[each].id == req.body.id) {res.send(_table.members[each]); bFound = true;}} - if (!bFound) {res.send({"id": req.body.id, "secret": "not found"});} -} \ No newline at end of file + { if (_table.members[each].id === req.body.id) {res.send(_table.members[each]); bFound = true;}} + if (!bFound) {res.send({'id': req.body.id, 'secret': 'not found'});} +}; \ No newline at end of file diff --git a/Chapter12/controller/restapi/features/composer/hlcAdmin.js b/Chapter12/controller/restapi/features/composer/hlcAdmin.js index 27b12a3..8e9e8b9 100644 --- a/Chapter12/controller/restapi/features/composer/hlcAdmin.js +++ b/Chapter12/controller/restapi/features/composer/hlcAdmin.js @@ -16,19 +16,16 @@ 'use strict'; const fs = require('fs'); const path = require('path'); +const _home = require('os').homedir(); +const hlc_idCard = require('composer-common').IdCard; const composerAdmin = require('composer-admin'); const AdminConnection = require('composer-admin').AdminConnection; -const composerClient = require('composer-client'); -const composerCommon = require('composer-common'); const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const Serializer = require('composer-common').Serializer; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; -const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); -var orderStatus = svc.orderStatus; - +// const svc = require('./Z2B_Services'); +// const mod = 'hlcAdmin.js'; /** * display the admin and network info @@ -56,7 +53,10 @@ exports.adminNew = function() { */ exports.adminConnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ console.log('create connection successful '); res.send({connection: 'succeeded'}); @@ -77,9 +77,6 @@ exports.adminConnect = function(req, res, next) { * @function */ exports.createProfile = function(req, res, next) { - let fields = ['fabric_type', 'orderers_url', 'ca_url', 'ca_name', 'peers_eventURL', 'peers_requestURL', - 'keyValStore', 'channel', 'mspID', 'timeout']; - let adminOptions = { type: req.body.type, keyValStore: req.body.keyValStore, @@ -91,18 +88,21 @@ exports.createProfile = function(req, res, next) { peers: [{eventURL: req.body.peers.eventURL, requestURL: req.body.peers.requestRUL}] }; let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.createProfile(req.body.profileName, adminOptions) - .then(function(result){ - console.log('create profile successful: '); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('create profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.createProfile(req.body.profileName, adminOptions) + .then(function(result){ + console.log('create profile successful: '); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('create profile failed: ',error); + res.send({profile: error}); + }); + }); }; /** * Deletes the specified connection profile from the profile store being used by this AdminConnection. @@ -115,19 +115,23 @@ exports.createProfile = function(req, res, next) { */ exports.deleteProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deleteProfile(req.body.profileName) - .then(function(result){ - console.log('delete profile successful: ',result); - res.send({profile: 'succeeded'}); - }) - .catch(function(error){ - console.log('delete profile failed: ',error); - res.send({profile: error}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deleteProfile(req.body.profileName) + .then(function(result){ + console.log('delete profile successful: ',result); + res.send({profile: 'succeeded'}); + }) + .catch(function(error){ + console.log('delete profile failed: ',error); + res.send({profile: error}); + }); + }); }; + /** * Deploys a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -135,31 +139,34 @@ exports.deleteProfile = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.deploy = function(req, res, next) { - let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); - let adminConnection = new composerAdmin.AdminConnection(); + let adminConnection = new composerAdmin.AdminConnection(); - return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.deploy(archive) - .then(function(){ - console.log('business network '+req.body.myArchive+' deployed successful: '); - res.send({deploy: req.body.myArchive+' deploy succeeded'}); - }) - .catch(function(error){ - console.log('business network '+req.body.myArchive+' deploy failed: ',error); - res.send({deploy: error}); - }); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.deploy(archive) + .then(function(){ + console.log('business network '+req.body.myArchive+' deployed successful: '); + res.send({deploy: req.body.myArchive+' deploy succeeded'}); + }) + .catch(function(error){ + console.log('business network '+req.body.myArchive+' deploy failed: ',error); + res.send({deploy: error}); }); - }); - }; + }); + }); +}; /** * Installs a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. * @param {express.req} req - the inbound request object from the client @@ -167,7 +174,7 @@ exports.deploy = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkInstall = function(req, res, next) { @@ -177,7 +184,10 @@ exports.networkInstall = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((businessNetworkDefinition) => { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(() => { return adminConnection.install(businessNetworkDefinition.getName()) .then(() => { @@ -187,15 +197,16 @@ exports.networkInstall = function(req, res, next) { .catch((error) => { console.log('business network '+req.body.myArchive+' error with adminConnection.install: ',error.message); res.send({install: error.message}); - }); - }) - .catch((error) => {console.log('error with adminConnection.connect', error.message) - res.send({install: error.message}); }); - }) - .catch((error) => {console.log('error with fromArchive', error.message)}); + }) + .catch((error) => {console.log('error with adminConnection.connect', error.message); + res.send({install: error.message}); + }); + }) + .catch((error) => {console.log('error with fromArchive', error.message); res.send({install: error.message}); - } + }); +}; /** * Starts a new BusinessNetworkDefinition to the Hyperledger Fabric. The connection must be connected for this method to succeed. @@ -204,16 +215,20 @@ exports.networkInstall = function(req, res, next) { * req.body.deployOptions: _object - string name of object * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.networkStart = function(req, res, next) { + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network/dist',req.body.myArchive)); let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) .then(function(){ adminConnection.start(archive) .then(function(){ @@ -223,10 +238,10 @@ exports.networkStart = function(req, res, next) { .catch(function(error){ console.log('business network '+req.body.myArchive+' install failed: ',error); res.send({install: error}); - }); - }); + }); }); - }; + }); +}; /** * disconnects this connection @@ -238,18 +253,21 @@ exports.networkStart = function(req, res, next) { */ exports.disconnect = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.disconnect() - .then(function(result){ - console.log('network disconnect successful: '); - res.send({disconnect: 'succeeded'}); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.disconnect() + .then(function(result){ + console.log('network disconnect successful: '); + res.send({disconnect: 'succeeded'}); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve all connection profiles from the profile store being used by this AdminConnection. @@ -261,17 +279,20 @@ exports.disconnect = function(req, res, next) { */ exports.getAllProfiles = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getAllProfiles() - .then((profiles) => { - res.send(profiles); - }) - .catch(function(error){ - console.log('network disconnect failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getAllProfiles() + .then((profiles) => { + res.send(profiles); + }) + .catch(function(error){ + console.log('network disconnect failed: ',error); + res.send(error); + }); + }); }; /** * Retrieve the specified connection profile from the profile store being used by this AdminConnection. @@ -284,18 +305,21 @@ exports.getAllProfiles = function(req, res, next) { */ exports.getProfile = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.getProfile(req.body.connectionProfile) - .then((profile) => { - console.log('get profile Succeeded: ',profile); - res.send(profile); - }) - .catch(function(error){ - console.log('get profile failed: ',error); - res.send(error); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.getProfile(req.body.connectionProfile) + .then((profile) => { + console.log('get profile Succeeded: ',profile); + res.send(profile); + }) + .catch(function(error){ + console.log('get profile failed: ',error); + res.send(error); + }); + }); }; /** * List all of the deployed business networks. The connection must be connected for this method to succeed. @@ -307,51 +331,27 @@ exports.getProfile = function(req, res, next) { */ exports.listAsAdmin = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - util.displayObjectValuesRecursive(adminConnection); // updated to use PeerAdmin, PeerPW to work with V0.14 - adminConnection.connect(config.composer.connectionProfile, config.composer.PeerAdmin, config.composer.PeerPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); - }); - }); -}; -/** - * List all of the deployed business networks. The connection must be connected for this method to succeed. - * @param {express.req} req - the inbound request object from the client - * @param {express.res} res - the outbound response object for communicating back to client - * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object - * @function - */ -exports.listAsPeerAdmin = function(req, res, next) { - let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(function(){ - adminConnection.list() - .then((businessNetworks) => { - // Connection has been tested - businessNetworks.forEach((businessNetwork) => { - console.log('Deployed business network', businessNetwork); - }); - res.send(businessNetworks); - }) - .catch(function(_error){ - let error = _error; - console.log('get business networks failed: ',error); - res.send(error); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + console.log('config.composer.PeerCard: '+config.composer.PeerCard); + adminConnection.connect(config.composer.PeerCard) + .then(function(){ + adminConnection.list() + .then((businessNetworks) => { + // Connection has been tested + businessNetworks.forEach((businessNetwork) => { + console.log('Deployed business network', businessNetwork); }); - }); + res.send(businessNetworks); + }) + .catch(function(_error){ + let error = _error; + console.log('get business networks failed: ',error); + res.send(error); + }); + }); }; /** * Test the connection to the runtime and verify that the version of the runtime is compatible with this level of the node.js module. @@ -363,19 +363,22 @@ exports.listAsPeerAdmin = function(req, res, next) { */ exports.ping = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.ping() - .then(function(result){ - console.log('network ping successful: ',result); - res.send({ping: result}); - }) - .catch(function(error){ - let _error = error; - console.log('network ping failed: '+_error); - res.send({ping: _error.toString()}); - }); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.ping() + .then(function(result){ + console.log('network ping successful: ',result); + res.send({ping: result}); + }) + .catch(function(error){ + let _error = error; + console.log('network ping failed: '+_error); + res.send({ping: _error.toString()}); + }); + }); }; /** * Undeploys a BusinessNetworkDefinition from the Hyperledger Fabric. The business network will no longer be able to process transactions. @@ -388,19 +391,22 @@ exports.ping = function(req, res, next) { */ exports.undeploy = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, req.body.businessNetwork) - .then(function(){ - adminConnection.undeploy(req.body.businessNetwork) - .then(function(result){ - console.log(req.body.businessNetwork+' network undeploy successful '); - res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.businessNetwork+' network undeploy failed: '+_error); - res.send({undeploy: _error.toString()}); - }); + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.undeploy(req.body.businessNetwork) + .then(function(result){ + console.log(req.body.businessNetwork+' network undeploy successful '); + res.send({undeploy: req.body.businessNetwork+' network undeploy successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.businessNetwork+' network undeploy failed: '+_error); + res.send({undeploy: _error.toString()}); }); + }); }; /** * Updates an existing BusinessNetworkDefinition on the Hyperledger Fabric. The BusinessNetworkDefinition must have been previously deployed. @@ -408,7 +414,7 @@ exports.undeploy = function(req, res, next) { * req.body.myArchive: _string - name of archive to deploy * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns composerAdmin.connection - either an error or a connection object + * @returns {composerAdmin.connection} - either an error or a connection object * @function */ exports.update = function(req, res, next) { @@ -419,21 +425,24 @@ exports.update = function(req, res, next) { let adminConnection = new composerAdmin.AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) - .then(function(archive) { - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW, netName) - .then(function(){ - adminConnection.update(archive) - .then(function(){ - console.log(netName+' network update successful: '); - res.send({update: req.body.myArchive+' network update successful '}); - }) - .catch(function(error){ - let _error = error; - console.log(req.body.myArchive+' network update failed: '+_error); - res.send({update: _error.toString()}); - }); - }); + .then(function(archive) { + // connection prior to V0.15 + // adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + adminConnection.connect(config.composer.adminCard) + .then(function(){ + adminConnection.update(archive) + .then(function(){ + console.log(netName+' network update successful: '); + res.send({update: req.body.myArchive+' network update successful '}); + }) + .catch(function(error){ + let _error = error; + console.log(req.body.myArchive+' network update failed: '+_error); + res.send({update: _error.toString()}); + }); }); + }); }; /** @@ -441,7 +450,7 @@ exports.update = function(req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns array of registries + * @returns {Object} array of registries * @function */ exports.getRegistries = function(req, res, next) @@ -450,29 +459,27 @@ exports.getRegistries = function(req, res, next) // connect to the network let allRegistries = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getAllParticipantRegistries() - .then(function(participantRegistries){ - for (let each in participantRegistries) - { (function (_idx, _arr) - { let r_type = _arr[_idx].name.split('.'); - allRegistries.push([r_type[r_type.length-1]]); - })(each, participantRegistries) - } - res.send({'result': 'success', 'registries': allRegistries}); - }) - .catch((error) => {console.log('error with getAllRegistries', error)}); - }) - .catch((error) => {console.log('error with business network Connect', error)}); + return businessNetworkConnection.getAllParticipantRegistries() + .then(function(participantRegistries){ + for (let each in participantRegistries) + { (function (_idx, _arr) + { + let r_type = _arr[_idx].name.split('.'); + allRegistries.push([r_type[r_type.length-1]]); + })(each, participantRegistries); + } + res.send({'result': 'success', 'registries': allRegistries}); + }) + .catch((error) => {console.log('error with getAllRegistries', error);}); }) - .catch((error) => {console.log('error with admin network Connect', error)}); -} + .catch((error) => {console.log('error with business network Connect', error);}); +}; /** * retrieve array of members from specified registry type @@ -480,66 +487,156 @@ exports.getRegistries = function(req, res, next) * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Object} an array of members * @function */ exports.getMembers = function(req, res, next) { // connect to the network + // let method = 'getMembers'; let allMembers = new Array(); let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - for (let each in members) - { (function (_idx, _arr) - { let _jsn = {}; - _jsn.type = req.body.registry; - _jsn.companyName = _arr[_idx].companyName; - switch (req.body.registry) - { - case 'Buyer': - _jsn.id = _arr[_idx].buyerID; - break; - case 'Seller': - _jsn.id = _arr[_idx].sellerID; - break; - case 'Provider': - _jsn.id = _arr[_idx].providerID; - break; - case 'Shipper': - _jsn.id = _arr[_idx].shipperID; - break; - case 'FinanceCo': - _jsn.id = _arr[_idx].financeCoID; - break; - default: - _jsn.id = _arr[_idx].id; - } - allMembers.push(_jsn); })(each, members) - } - res.send({'result': 'success', 'members': allMembers}); - }) - .catch((error) => {console.log('error with getAllMembers', error); - res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with getRegistry', error); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + for (let each in members) + { (function (_idx, _arr) + { let _jsn = {}; + _jsn.type = req.body.registry; + _jsn.companyName = _arr[_idx].companyName; + switch (req.body.registry) + { + case 'Buyer': + _jsn.id = _arr[_idx].buyerID; + break; + case 'Seller': + _jsn.id = _arr[_idx].sellerID; + break; + case 'Provider': + _jsn.id = _arr[_idx].providerID; + break; + case 'Shipper': + _jsn.id = _arr[_idx].shipperID; + break; + case 'FinanceCo': + _jsn.id = _arr[_idx].financeCoID; + break; + default: + _jsn.id = _arr[_idx].id; + } + allMembers.push(_jsn); })(each, members); + } + res.send({'result': 'success', 'members': allMembers}); + }) + .catch((error) => {console.log('error with getAllMembers', error); res.send({'result': 'failed '+error.message, 'members': []});}); - }) - .catch((error) => {console.log('error with business network Connect', error.message); - res.send({'result': 'failed '+error.message, 'members': []});}); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed '+error.message, 'members': []});}); }) - .catch((error) => {console.log('error with admin network Connect', error); - res.send({'result': 'failed '+error.message, 'members': []});}); + .catch((error) => {console.log('error with business network Connect', error.message); + res.send({'result': 'failed '+error.message, 'members': []});}); +}; -} +/** + * Checks to see if the provided id already has a card issued for it + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.checkCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + adminConnection.connect(config.composer.adminCard) + .then(() => {adminConnection.hasCard(req.body.id) + .then((_res) => { + let cardState = ((_res) ? 'exists' : 'does not exist'); + res.send({'result': 'success', 'card': cardState}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'admin Connect failed', 'message': error.message}); + }); +}; + +/** + * Creates a card for an existing member + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.pw - the pw of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * returns {object} - a JSON object + * @function + */ +exports.createCard = function(req, res, next) { + let adminConnection = new AdminConnection(); + let _meta = {}; + for (let each in config.composer.metaData) + {(function(_idx, _obj) {_meta[_idx] = _obj[_idx]; })(each, config.composer.metaData); } + _meta.businessNetwork = config.composer.network; + _meta.userName = req.body.id; + _meta.enrollmentSecret = req.body.secret; + config.connectionProfile.keyValStore = _home+config.connectionProfile.keyValStore; + let tempCard = new hlc_idCard(_meta, config.connectionProfile); + adminConnection.connect(config.composer.adminCard) + .then(() => { + return adminConnection.importCard(req.body.id, tempCard) + .then ((_res) => { let _msg = ((_res) ? 'card updated' : 'card imported'); + console.log('create Card succeeded:'+_msg); + res.send({'result': 'success', 'card': _msg}); + }) + .catch((error) => { + console.error('adminConnection.importCard failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); + }) + .catch((error) => { + console.error('adminConnection.connect failed. ',error.message); + res.send({'result': 'failed', 'error': error.message}); + }); +}; + +/** + * creates an identity for a member already created in a member registry + * @param {express.req} req - the inbound request object from the client + * req.body.id - the id of the individual making the request + * req.body.type - the member type of the individual making the request + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {object} - a JSON object + * @function + */ +exports.issueIdentity = function(req, res, next) { + let businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + console.log('issuing identity for: '+config.composer.NS+'.'+req.body.type+'#'+req.body.id); + return businessNetworkConnection.issueIdentity(config.composer.NS+'.'+req.body.type+'#'+req.body.id, req.body.id) + .then((result) => { + console.log('result.userID: '+result.userID); + console.log('result.userSecret: '+result.userSecret); + res.send({'result': 'success', 'userID': result.userID, 'secret': result.userSecret}); + }) + .catch((error) => { + res.send({'result': 'failed', 'message': error.message}); + }); + }) + .catch((error) => { + res.send({'result': 'business network Connect failed', 'message': error.message}); + }); +}; /** * gets the assets from the order registry @@ -548,87 +645,83 @@ exports.getMembers = function(req, res, next) { * req.body.id - the id of the individual making the request * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} - an array of assets * @function */ exports.getAssets = function(req, res, next) { - // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); - let allOrders = new Array(); - let businessNetworkConnection; - let factory; - let serializer; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) + // connect to the network + let allOrders = new Array(); + let businessNetworkConnection; + let serializer; + let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); + businessNetworkConnection = new BusinessNetworkConnection(); + return BusinessNetworkDefinition.fromArchive(archiveFile) + .then((bnd) => { + serializer = bnd.getSerializer(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { -// let bnd = new BusinessNetworkDefinition(config.composer.network+'@0.1.6', config.composer.description, packageJSON); -// retry this with fromArchive when time allows -// serializer = bnd.getSerializer(); - return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) - .then(function(registry){ - return registry.getAll() - .then ((members) => { - console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); - for (let each in members) - { (function (_idx, _arr) + return businessNetworkConnection.getAssetRegistry(NS+'.'+req.body.registry) + .then(function(registry){ + return registry.getAll() + .then ((members) => { + console.log('there are '+members.length+' entries in the '+req.body.registry+' Registry with id: '+members[0].$namespace); + for (let each in members) + { (function (_idx, _arr) + { + switch(req.body.type) + { + case 'Buyer': + if (req.body.id === _arr[_idx].buyer.$identifier) { - switch(req.body.type) + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) { - case 'Buyer': - if (req.body.id == _arr[_idx].buyer.$identifier) - { - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - } - break; - case 'admin': - let _jsn = svc.getOrderData(_arr[_idx]); - _jsn.type = req.body.registry; - switch (req.body.registry) - { - case 'Order': - _jsn.id = _arr[_idx].orderNumber; - break; - default: - _jsn.id = _arr[_idx].id; - } - allOrders.push(_jsn); - break; - default: + case 'Order': + _jsn.id = _arr[_idx].orderNumber; break; + default: + _jsn.id = _arr[_idx].id; } - })(each, members) + allOrders.push(_jsn); + } + break; + case 'admin': + let _jsn = serializer.toJSON(_arr[_idx]); + _jsn.type = req.body.registry; + switch (req.body.registry) + { + case 'Order': + _jsn.id = _arr[_idx].orderNumber; + break; + default: + _jsn.id = _arr[_idx].id; + } + allOrders.push(_jsn); + break; + default: + break; } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('error with getAllOrders', error) - res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('error with getRegistry', error) - res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); - }); + })(each, members); + } + res.send({'result': 'success', 'orders': allOrders}); }) - .catch((error) => {console.log('error with business network Connect', error) - res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + .catch((error) => {console.log('error with getAllOrders', error); + res.send({'result': 'failed', 'error': 'getAllOrders: '+error.message}); + }); + }) + .catch((error) => {console.log('error with getRegistry', error); + res.send({'result': 'failed', 'error': 'getRegistry: '+error.message}); }); - }) - .catch((error) => {console.log('error with admin network Connect', error) - res.send({'result': 'failed', 'error': 'admin network Connect: '+error.message}); - }); -} + }) + .catch((error) => {console.log('error with business network Connect', error); + res.send({'result': 'failed', 'error': 'business network Connect: '+error.message}); + }); + }); +}; /** * Adds a new member to the specified registry @@ -638,38 +731,36 @@ exports.getAssets = function(req, res, next) { * req.body.id: _string - id of member to add (email address) * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.addMember = function(req, res, next) { let businessNetworkConnection; let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { res.send('member already exists. add cancelled');}) - .catch((_res) => { - console.log(req.body.id+' not in '+req.body.type+' registry. '); - let participant = factory.newResource(NS, req.body.type,req.body.id); - participant.companyName = req.body.companyName; - participantRegistry.add(participant) - .then(() => {console.log(req.body.companyName+" successfully added"); res.send(req.body.companyName+" successfully added");}) - .catch((error) => {console.log(req.body.companyName+" add failed",error); res.send(error);}); - }); - }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); - }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); - }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error);}); -} + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.type) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { res.send('member already exists. add cancelled');}) + .catch((_res) => { + console.log(req.body.id+' not in '+req.body.type+' registry. '); + let participant = factory.newResource(NS, req.body.type,req.body.id); + participant.companyName = req.body.companyName; + participantRegistry.add(participant) + .then(() => {console.log(req.body.companyName+' successfully added'); res.send(req.body.companyName+' successfully added');}) + .catch((error) => {console.log(req.body.companyName+' add failed',error); res.send(error);}); + }); + }) + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error);}); +}; /** * Removes a member from a registry. @@ -678,38 +769,35 @@ exports.addMember = function(req, res, next) { * req.body.id: _string - id of member to delete * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns JSON object with success or error results + * @returns {JSON} object with success or error results * @function */ exports.removeMember = function(req, res, next) { let businessNetworkConnection; - let factory; - let adminConnection = new AdminConnection(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) - .then(function(participantRegistry){ - return participantRegistry.get(req.body.id) - .then((_res) => { - return participantRegistry.remove(req.body.id) - .then((_res) => { - res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); - res.send('member already exists. add cancelled'); - }) - .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getParticipantRegistry(NS+'.'+req.body.registry) + .then(function(participantRegistry){ + return participantRegistry.get(req.body.id) + .then((_res) => { + return participantRegistry.remove(req.body.id) + .then((_res) => { + res.send('member id '+req.body.id+' successfully removed from the '+req.body.registry+' member registry.'); }) - .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.'); + res.send('member already exists. add cancelled'); + }); }) - .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); + .catch((_res) => { res.send('member id '+req.body.id+' does not exist in the '+req.body.registry+' member registry.');}); }) - .catch((error) => {console.log('error with adminConnection', error); res.send(error.message);}); -} + .catch((error) => {console.log('error with getParticipantRegistry', error); res.send(error.message);}); + }) + .catch((error) => {console.log('error with businessNetworkConnection', error); res.send(error.message);}); +}; /** * get Historian Records @@ -717,43 +805,40 @@ exports.removeMember = function(req, res, next) { * req.body.registry: _string - type of registry to search; e.g. 'Buyer', 'Seller', etc. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of members + * @returns {Array} an array of members * @function */ exports.getHistory = function(req, res, next) { let allHistory = new Array(); let businessNetworkConnection; - let factory; let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); - let adminConnection = new AdminConnection(); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - adminConnection.connect(config.composer.connectionProfile, config.composer.adminID, config.composer.adminPW) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) - .then(() => { - return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') - .then(function(registry){ - return registry.getAll() - .then ((history) => { - for (let each in history) - { (function (_idx, _arr) - { let _jsn = _arr[_idx]; - allHistory.push(ser.toJSON(_jsn)); - })(each, history) - } - res.send({'result': 'success', 'history': allHistory}); - }) - .catch((error) => {console.log('error with getAll History', error)}); - }) - .catch((error) => {console.log('error with getRegistry', error)}); + businessNetworkConnection = new BusinessNetworkConnection(); + // connection prior to V0.15 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // connection in v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) + .then(() => { + return businessNetworkConnection.getRegistry('org.hyperledger.composer.system.HistorianRecord') + .then(function(registry){ + return registry.getAll() + .then ((history) => { + for (let each in history) + { (function (_idx, _arr) + { let _jsn = _arr[_idx]; + allHistory.push(ser.toJSON(_jsn)); + })(each, history); + } + res.send({'result': 'success', 'history': allHistory}); }) - .catch((error) => {console.log('error with business network Connect', error)}); - }) - .catch((error) => {console.log('error with admin network Connect', error)}); + .catch((error) => {console.log('error with getAll History', error);}); + }) + .catch((error) => {console.log('error with getRegistry', error);}); + }) + .catch((error) => {console.log('error with business network Connect', error);}); }) - .catch((error) => {console.log('error with business network definition', error)}); -} + .catch((error) => {console.log('error with admin network Connect', error);}); +}; diff --git a/Chapter12/controller/restapi/features/composer/hlcClient.js b/Chapter12/controller/restapi/features/composer/hlcClient.js index c8b25ed..7fb32ee 100644 --- a/Chapter12/controller/restapi/features/composer/hlcClient.js +++ b/Chapter12/controller/restapi/features/composer/hlcClient.js @@ -14,15 +14,14 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +let fs = require('fs'); +let path = require('path'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; const config = require('../../../env.json'); const NS = 'org.acme.Z2BTestNetwork'; let itemTable = null; const svc = require('./Z2B_Services'); -const util = require('./Z2B_Utilities'); const financeCoID = 'easymoney@easymoneyinc.com'; let bRegistered = false; @@ -31,54 +30,58 @@ let bRegistered = false; * @param {express.req} req - the inbound request object from the client * req.body.id - the id of the buyer making the request * req.body.userID - the user id of the buyer in the identity table making this request - * req.body.secret - the pw of this user. + * req.body.secret - the pw of this user. * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.getMyOrders = function (req, res, next) { // connect to the network - let packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(require.main.filename),'network','package.json'))); + let method = 'getMyOrders'; + console.log(method+' req.body.userID is: '+req.body.userID ); let allOrders = new Array(); let businessNetworkConnection; - let factory; - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let ser; let archiveFile = fs.readFileSync(path.join(path.dirname(require.main.filename),'network','dist','zerotoblockchain-network.bna')); businessNetworkConnection = new BusinessNetworkConnection(); - businessNetworkConnection.setMaxListeners(50); return BusinessNetworkDefinition.fromArchive(archiveFile) .then((bnd) => { ser = bnd.getSerializer(); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) - .then(() => { - return businessNetworkConnection.query('selectOrders') - .then((orders) => { - let jsn; - let allOrders = new Array(); - for (let each in orders) - { (function (_idx, _arr) - { - let _jsn = ser.toJSON(_arr[_idx]); - _jsn.id = _arr[_idx].orderNumber; - allOrders.push(_jsn); - })(each, orders) - } - res.send({'result': 'success', 'orders': allOrders}); - }) - .catch((error) => {console.log('selectOrders failed ', error); - res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); - }); - }) - .catch((error) => {console.log('businessNetwork connect failed ', error); - res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.userID, req.body.secret) + // + // v0.15 + console.log(method+' req.body.userID is: '+req.body.userID ); + return businessNetworkConnection.connect(req.body.userID) + .then(() => { + return businessNetworkConnection.query('selectOrders') + .then((orders) => { + allOrders = new Array(); + for (let each in orders) + { (function (_idx, _arr) + { + let _jsn = ser.toJSON(_arr[_idx]); + _jsn.id = _arr[_idx].orderNumber; + allOrders.push(_jsn); + })(each, orders); + } + res.send({'result': 'success', 'orders': allOrders}); + }) + .catch((error) => {console.log('selectOrders failed ', error); + res.send({'result': 'failed', 'error': 'selectOrders: '+error.message}); }); }) - .catch((error) => {console.log('create bnd from archive failed ', error); + .catch((error) => {console.log('businessNetwork connect failed ', error); + res.send({'result': 'failed', 'error': 'businessNetwork: '+error.message}); + }); + }) + .catch((error) => {console.log('create bnd from archive failed ', error); res.send({'result': 'failed', 'error': 'create bnd from archive: '+error.message}); }); -} +}; /** @@ -86,24 +89,24 @@ exports.getMyOrders = function (req, res, next) { * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * return {Array} an array of assets * @function */ exports.getItemTable = function (req, res, next) { - if (itemTable == null) + if (itemTable === null) { - let options = { flag : 'w' }; let newFile = path.join(path.dirname(require.main.filename),'startup','itemList.txt'); itemTable = JSON.parse(fs.readFileSync(newFile)); } res.send(itemTable); -} +}; + /** * orderAction - act on an order for a buyer * @param {express.req} req - the inbound request object from the client * req.body.action - string with buyer requested action - * buyer available actions are: + * buyer available actions are: * Pay - approve payment for an order * Dispute - dispute an existing order. requires a reason * Purchase - submit created order to seller for execution @@ -113,156 +116,156 @@ exports.getItemTable = function (req, res, next) * req.body.reason - reason for dispute, required for dispute processing to proceed * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.orderAction = function (req, res, next) { - if ((req.body.action == 'Dispute') && (typeof(req.body.reason) != 'undefined') && (req.body.reason.length > 0) ) - {let reason = req.body.reason;} + let method = 'orderAction'; + console.log(method+' req.body.participant is: '+req.body.participant ); + if ((req.body.action === 'Dispute') && (typeof(req.body.reason) !== 'undefined') && (req.body.reason.length > 0) ) + {/*let reason = req.body.reason;*/} else { - if ((req.body.action == 'Dispute') && ((typeof(req.body.reason) == 'undefined') || (req.body.reason.length <1) )) - res.send({'result': 'failed', 'error': 'no reason provided for dispute'}); + if ((req.body.action === 'Dispute') && ((typeof(req.body.reason) === 'undefined') || (req.body.reason.length <1) )) + {res.send({'result': 'failed', 'error': 'no reason provided for dispute'});} } - if (svc.m_connection == null) {svc.createMessageSocket();} + if (svc.m_connection === null) {svc.createMessageSocket();} let businessNetworkConnection; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let updateOrder; - for (let each in _table.members) - { if (_table.members[each].id == req.body.participant) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - businessNetworkConnection.setMaxListeners(50); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.get(req.body.orderNo) - .then((order) => { - let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - order.status = req.body.action; - switch (req.body.action) - { - case 'Pay': - console.log('Pay entered'); - updateOrder = factory.newTransaction(NS, 'Pay'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Dispute': - console.log('Dispute entered'); - updateOrder = factory.newTransaction(NS, 'Dispute'); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.dispute = req.body.reason; - break; - case 'Purchase': - console.log('Purchase entered'); - updateOrder = factory.newTransaction(NS, 'Buy'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Order From Supplier': - console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ _userID+' with order.seller as: '+order.seller.$identifier); - updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); - updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - case 'Request Payment': - console.log('Request Payment entered'); - updateOrder = factory.newTransaction(NS, 'RequestPayment'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Refund': - console.log('Refund Payment entered'); - updateOrder = factory.newTransaction(NS, 'Refund'); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.refund = req.body.reason; - break; - case 'Resolve': - console.log('Resolve entered'); - updateOrder = factory.newTransaction(NS, 'Resolve'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - updateOrder.resolve = req.body.reason; - break; - case 'Request Shipping': - console.log('Request Shipping entered'); - updateOrder = factory.newTransaction(NS, 'RequestShipping'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - break; - case 'Update Delivery Status': - console.log('Update Delivery Status'); - updateOrder = factory.newTransaction(NS, 'Delivering'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - updateOrder.deliveryStatus = req.body.delivery; - break; - case 'Delivered': - console.log('Delivered entered'); - updateOrder = factory.newTransaction(NS, 'Deliver'); - updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); - break; - case 'BackOrder': - console.log('BackOrder entered'); - updateOrder = factory.newTransaction(NS, 'BackOrder'); - updateOrder.backorder = req.body.reason; - updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); - updateOrder.backorder = req.body.reason; - break; - case 'Authorize Payment': - console.log('Authorize Payment entered'); - updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - break; - case 'Cancel': - console.log('Cancel entered'); - updateOrder = factory.newTransaction(NS, 'OrderCancel'); - updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); - updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); - break; - default : - console.log('default entered for action: '+req.body.action); - res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); - } - updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); - return businessNetworkConnection.submitTransaction(updateOrder) - .then(() => { - console.log(' order '+req.body.orderNo+" successfully updated to "+req.body.action); - res.send({'result': ' order '+req.body.orderNo+" successfully updated to "+req.body.action}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(" retrying assetRegistry.update for: "+req.body.orderNo); - svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); - } - else - {console.log(req.body.orderNo+" submitTransaction to update status to "+req.body.action+" failed with text: ",error.message);} - }); - + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.participant, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.participant) + .then(() => { + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.get(req.body.orderNo) + .then((order) => { + let factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + order.status = req.body.action; + switch (req.body.action) + { + case 'Pay': + console.log('Pay entered'); + updateOrder = factory.newTransaction(NS, 'Pay'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Dispute': + console.log('Dispute entered'); + updateOrder = factory.newTransaction(NS, 'Dispute'); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.dispute = req.body.reason; + break; + case 'Purchase': + console.log('Purchase entered'); + updateOrder = factory.newTransaction(NS, 'Buy'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Order From Supplier': + console.log('Order from Supplier entered for '+order.orderNumber+ ' inbound id: '+ req.body.participant+' with order.seller as: '+order.seller.$identifier); + updateOrder = factory.newTransaction(NS, 'OrderFromSupplier'); + updateOrder.provider = factory.newRelationship(NS, 'Provider', req.body.provider); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + case 'Request Payment': + console.log('Request Payment entered'); + updateOrder = factory.newTransaction(NS, 'RequestPayment'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Refund': + console.log('Refund Payment entered'); + updateOrder = factory.newTransaction(NS, 'Refund'); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.refund = req.body.reason; + break; + case 'Resolve': + console.log('Resolve entered'); + updateOrder = factory.newTransaction(NS, 'Resolve'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', order.shipper.$identifier); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + updateOrder.resolve = req.body.reason; + break; + case 'Request Shipping': + console.log('Request Shipping entered'); + updateOrder = factory.newTransaction(NS, 'RequestShipping'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.shipper); + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + break; + case 'Update Delivery Status': + console.log('Update Delivery Status'); + updateOrder = factory.newTransaction(NS, 'Delivering'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + updateOrder.deliveryStatus = req.body.delivery; + break; + case 'Delivered': + console.log('Delivered entered'); + updateOrder = factory.newTransaction(NS, 'Deliver'); + updateOrder.shipper = factory.newRelationship(NS, 'Shipper', req.body.participant); + break; + case 'BackOrder': + console.log('BackOrder entered'); + updateOrder = factory.newTransaction(NS, 'BackOrder'); + updateOrder.backorder = req.body.reason; + updateOrder.provider = factory.newRelationship(NS, 'Provider', order.provider.$identifier); + updateOrder.backorder = req.body.reason; + break; + case 'Authorize Payment': + console.log('Authorize Payment entered'); + updateOrder = factory.newTransaction(NS, 'AuthorizePayment'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + break; + case 'Cancel': + console.log('Cancel entered'); + updateOrder = factory.newTransaction(NS, 'OrderCancel'); + updateOrder.buyer = factory.newRelationship(NS, 'Buyer', order.buyer.$identifier); + updateOrder.seller = factory.newRelationship(NS, 'Seller', order.seller.$identifier); + break; + default : + console.log('default entered for action: '+req.body.action); + res.send({'result': 'failed', 'error':' order '+req.body.orderNo+' unrecognized request: '+req.body.action}); + } + updateOrder.order = factory.newRelationship(NS, 'Order', order.$identifier); + return businessNetworkConnection.submitTransaction(updateOrder) + .then(() => { + console.log(' order '+req.body.orderNo+' successfully updated to '+req.body.action); + res.send({'result': ' order '+req.body.orderNo+' successfully updated to '+req.body.action}); }) .catch((error) => { - console.log('Registry Get Order failed: '+error.message); - res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(' retrying assetRegistry.update for: '+req.body.orderNo); + svc.loadTransaction(svc.m_connection, updateOrder, req.body.orderNo, businessNetworkConnection); + } + else + {console.log(req.body.orderNo+' submitTransaction to update status to '+req.body.action+' failed with text: ',error.message);} }); + }) - .catch((error) => {console.log('Get Asset Registry failed: '+error.message); + .catch((error) => { + console.log('Registry Get Order failed: '+error.message); + res.send({'result': 'failed', 'error': 'Registry Get Order failed: '+error.message}); + }); + }) + .catch((error) => {console.log('Get Asset Registry failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); - }) - .catch((error) => {console.log('Business Network Connect failed: '+error.message); + }) + .catch((error) => {console.log('Business Network Connect failed: '+error.message); res.send({'result': 'failed', 'error': 'Get Asset Registry failed: '+error.message}); }); -} +}; + /** * adds an order to the blockchain * @param {express.req} req - the inbound request object from the client @@ -271,173 +274,175 @@ exports.orderAction = function (req, res, next) { * req.body.items - array with items for order * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client - * returns an array of assets + * @returns {Array} an array of assets * @function */ exports.addOrder = function (req, res, next) { + let method = 'addOrder'; + console.log(method+' req.body.buyer is: '+req.body.buyer ); let businessNetworkConnection; let factory; - let newFile = path.join(path.dirname(require.main.filename),'startup','memberList.txt'); - let _table = JSON.parse(fs.readFileSync(newFile)); - let _userID = ''; let _secret = ''; - let bFound = false; let ts = Date.now(); - let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; - if (svc.m_connection == null) {svc.createMessageSocket();} - - for (let each in _table.members) - { if (_table.members[each].id == req.body.buyer) {_secret = _table.members[each].secret; _userID=_table.members[each].userID; bFound = true;}} - if (!bFound) {res.send({'result':req.body.id + 'not found'});} - businessNetworkConnection = new BusinessNetworkConnection(); - businessNetworkConnection.setMaxListeners(50); - return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, _userID, _secret) - .then(() => { - factory = businessNetworkConnection.getBusinessNetwork().getFactory(); - let order = factory.newResource(NS, 'Order', orderNo); - order = svc.createOrderTemplate(order); - order.amount = 0; - order.orderNumber = orderNo; - order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); - order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); - order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - for (let each in req.body.items) - {(function(_idx, _arr) - { _arr[_idx].description = _arr[_idx].itemDescription; - order.items.push(JSON.stringify(_arr[_idx])); - order.amount += parseInt(_arr[_idx].extendedPrice); - })(each, req.body.items) - } - // create the buy transaction - const createNew = factory.newTransaction(NS, 'CreateOrder'); - - createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); - createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); - createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); - createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); - createNew.amount = order.amount; - // add the order to the asset registry. - return businessNetworkConnection.getAssetRegistry(NS+'.Order') - .then((assetRegistry) => { - return assetRegistry.add(order) - .then(() => { - return businessNetworkConnection.submitTransaction(createNew) - .then(() => {console.log(' order '+orderNo+" successfully added"); - res.send({'result': ' order '+orderNo+' successfully added'}); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" submitTransaction failed with text: ",error.message);} - }); - }) - .catch((error) => { - if (error.message.search('MVCC_READ_CONFLICT') != -1) - {console.log(orderNo+" retrying assetRegistry.add for: "+orderNo); - svc.loadTransaction(createNew, orderNo, businessNetworkConnection); - } - else - {console.log(orderNo+" assetRegistry.add failed: ",error.message);} - }); - }) - .catch((error) => { - console.log(orderNo+" getAssetRegistry failed: ",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); - }); - }) - .catch((error) => { - console.log(orderNo+" business network connection failed: text",error.message); - res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); - }); + let orderNo = req.body.buyer.replace(/@/, '').replace(/\./, '')+ts; + if (svc.m_connection === null) {svc.createMessageSocket();} + businessNetworkConnection = new BusinessNetworkConnection(); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, req.body.buyer, req.body.secret) + // + // v0.15 + return businessNetworkConnection.connect(req.body.buyer) + .then(() => { + factory = businessNetworkConnection.getBusinessNetwork().getFactory(); + let order = factory.newResource(NS, 'Order', orderNo); + order = svc.createOrderTemplate(order); + order.amount = 0; + order.orderNumber = orderNo; + order.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + order.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + order.provider = factory.newRelationship(NS, 'Provider', 'noop@dummy'); + order.shipper = factory.newRelationship(NS, 'Shipper', 'noop@dummy'); + order.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + for (let each in req.body.items) + {(function(_idx, _arr) + { _arr[_idx].description = _arr[_idx].itemDescription; + order.items.push(JSON.stringify(_arr[_idx])); + order.amount += parseInt(_arr[_idx].extendedPrice); + })(each, req.body.items); } + // create the buy transaction + const createNew = factory.newTransaction(NS, 'CreateOrder'); + + createNew.order = factory.newRelationship(NS, 'Order', order.$identifier); + createNew.buyer = factory.newRelationship(NS, 'Buyer', req.body.buyer); + createNew.seller = factory.newRelationship(NS, 'Seller', req.body.seller); + createNew.financeCo = factory.newRelationship(NS, 'FinanceCo', financeCoID); + createNew.amount = order.amount; + // add the order to the asset registry. + return businessNetworkConnection.getAssetRegistry(NS+'.Order') + .then((assetRegistry) => { + return assetRegistry.add(order) + .then(() => { + return businessNetworkConnection.submitTransaction(createNew) + .then(() => {console.log(' order '+orderNo+' successfully added'); + res.send({'result': ' order '+orderNo+' successfully added'}); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + {console.log(orderNo+' submitTransaction failed with text: ',error.message);} + }); + }) + .catch((error) => { + if (error.message.search('MVCC_READ_CONFLICT') !== -1) + {console.log(orderNo+' retrying assetRegistry.add for: '+orderNo); + svc.loadTransaction(createNew, orderNo, businessNetworkConnection); + } + else + { + console.log(orderNo+' assetRegistry.add failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + } + }); + }) + .catch((error) => { + console.log(orderNo+' getAssetRegistry failed: ',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' getAssetRegistry failed '+error.message}); + }); + }) + .catch((error) => { + console.log(orderNo+' business network connection failed: text',error.message); + res.send({'result': 'failed', 'error':' order '+orderNo+' add failed on on business network connection '+error.message}); + }); +}; /** * Register for all of the available Z2BEvents * @param {express.req} req - the inbound request object from the client * @param {express.res} res - the outbound response object for communicating back to client * @param {express.next} next - an express service to enable post processing prior to responding to the client + * @returns {Object} - returns are via res.send */ exports.init_z2bEvents = function (req, res, next) { - var method = 'init_z2bEvents'; - // check to see if we're already registered. Don't want to overload the system with duplicate event monitoring + let method = 'init_z2bEvents'; if (bRegistered) {res.send('Already Registered');} else{ bRegistered = true; - // create an alert socket using the capability in Z2B_Services - - // create a new business network connection - - // connect to the business network using the data and admin id and password from the env.json file - + let _conn = svc.createAlertSocket(); + let businessNetworkConnection; + businessNetworkConnection = new BusinessNetworkConnection(); + businessNetworkConnection.setMaxListeners(50); + // + // v0.14 + // return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW) + // + // v0.15 + return businessNetworkConnection.connect(config.composer.adminCard) .then(() => { - // monitor for events and call the _monitor function when an event is received - - // we're only listening for 1 event. Send a message back to the browser on success. - + // using the businessNetworkConnection, start monitoring for events. + // when an event is provided, call the _monitor function, passing in the al_connection, f_connection and event information + // ========> Your Code Goes Here <========= + res.send('event registration complete'); }).catch((error) => { - // if the monitor request failed, log it and send a failed message back to the browser - + // if an error is encountered, log the error and send it back to the requestor + // ========> Your Code Goes Here <========= + res.send(method+' business network connection failed'+error.message); }); } -} +}; /** * _monitor - * @param {org.acme.z2bNetwork.Event} _event - the event just emitted - * + * @param {WebSocket} _conn - web socket to use for member event posting + * @param {WebSocket} _f_conn - web sockect to use for FinanceCo event posting + * @param {Event} _event - the event just emitted + * */ function _monitor(_conn, _f_conn, _event) { - // let's log each received event - var method = '_monitor'; + let method = '_monitor'; console.log(method+ ' _event received: '+_event.$type+' for Order: '+_event.orderID); - // create an event object and populate it with everything needed for an Order Creation event - // hint, look in the sample.cto and sample.js files to know what to use here. - var event = {}; - + // create an event object and give it the event type, the orderID, the buyer id and the eventID + // send that event back to the requestor + // ========> Your Code Goes Here <========= + // using switch/case logic, send events back to each participant who should be notified. + // for example, when a seller requests payment, they should be notified when the transaction has completed + // and the financeCo should be notified at the same time. + // so you would use the _conn connection to notify the seller and the + // _f_conn connection to notify the financeCo + switch (_event.$type) { - case 'Created': - // send an event back to the browser - - break; - case 'Bought': - case 'PaymentRequested': - // these events send notifications to the same users - // the finance ID uses a different connector, so that you can open it in a different window and still receive alerts. - - break; - case 'Ordered': - case 'Cancelled': - case 'Backordered': - // these events send notifications to the same users - - break; - case 'ShipRequest': - case 'DeliveryStarted': - case 'DeliveryCompleted': - // these events send notifications to the same users - - break; - case 'DisputeOpened': - case 'Resolved': - case 'Refunded': - case 'Paid': - // these events send notifications to the same users - // the finance ID uses a different connector, so that you can open it in a different window and still receive alerts. - - break; - case 'PaymentAuthorized': - // these events send notifications to the same users - // the finance ID uses a different connector, so that you can open it in a different window and still receive alerts. - - break; - default: + case 'Created': + break; + case 'Bought': + case 'PaymentRequested': + // ========> Your Code Goes Here <========= + break; + case 'Ordered': + case 'Cancelled': + case 'Backordered': + // ========> Your Code Goes Here <========= + break; + case 'ShipRequest': + case 'DeliveryStarted': + case 'DeliveryCompleted': + // ========> Your Code Goes Here <========= + break; + case 'DisputeOpened': + case 'Resolved': + case 'Refunded': + case 'Paid': + // ========> Your Code Goes Here <========= + break; + case 'PaymentAuthorized': + // ========> Your Code Goes Here <========= + break; + default: break; } diff --git a/Chapter12/controller/restapi/features/text/ch/prompts.json b/Chapter12/controller/restapi/features/text/ch/prompts.json index bd83775..40ed147 100644 --- a/Chapter12/controller/restapi/features/text/ch/prompts.json +++ b/Chapter12/controller/restapi/features/text/ch/prompts.json @@ -1,7 +1,7 @@ { "index": {"language":"美式英语", "title":"Z2B 第12章", - "header":"第12章: 集成用户视图", + "header":"第12章: 事件的处理", "titleBar":"从0到区块链教程", "idx_unified":"导入统一的用户体验", "idx_buyer":"导入买家用户体验", @@ -15,7 +15,7 @@ "idx_preload":"预先导入网络" }, "admin": { - "title":"从0到区块链 第12章", + "title":"从0到区块链 第5章", "npm":"网络配置文件管理", "npm_API":"API", "npm_param":"参数", @@ -54,6 +54,9 @@ "rm_am_param":"Co 名字,ID, 类型", "rm_rm_api":"删除成员", "rm_gs_api":"获取成员秘密", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", "bc":"区块链", "bc_api":"API", "bc_param":"参数", @@ -65,7 +68,7 @@ "bc_gh_param":"(无)" }, "buyer": { - "title":"买家第12章. 选择买家看它们的视图", + "title":"买家第6章. 选择买家看它们的视图", "newOrder":"创建新订单", "orderStatus":"显示订单状态" }, @@ -96,8 +99,8 @@ "cd_financeco":"FinanceCo", "cd_cn":"公司名称", "cd_e":"电子邮箱地址", - "cancelNewOrder":"取消", - "submitNewOrder":"提交" + "cancel":"取消", + "submit":"提交" }, "createOrder": { "title":"创建新订单", @@ -117,7 +120,7 @@ "submit":"提交" }, "financeCo": { - "title":"从0到区块链 第12章:全球金融家", + "title":"从0到区块链 第10章:全球金融家", "financeCOclear":"清除窗口", "financeCOorderStatus":"显示订单状态“" }, @@ -132,7 +135,7 @@ "submit":"提交" }, "provider": { - "title":"提供商第12章. 选择提供商看它们的视图", + "title":"提供商第8章. 选择提供商看它们的视图", "provider_clear":"清除窗口", "providerOrderStatus":"显示订单状态" }, @@ -147,12 +150,12 @@ "submit":"提交" }, "seller": { - "title":"卖家 第12章. 选择卖家看它们的视图", + "title":"卖家 第7章. 选择卖家看它们的视图", "seller_clear":"清除窗口", "sellerOrderStatus":"显示订单状态" }, "shipper": { - "title":"发货商第12章. 选择发货商看它们的视图", + "title":"发货商第9章. 选择发货商看它们的视图", "shipper_clear":"清除窗口", "shipperOrderStatus":"显示订单状态" }, diff --git a/Chapter12/controller/restapi/features/text/en-UK/prompts.json b/Chapter12/controller/restapi/features/text/en-UK/prompts.json index 8accb3a..09ff3b1 100644 --- a/Chapter12/controller/restapi/features/text/en-UK/prompts.json +++ b/Chapter12/controller/restapi/features/text/en-UK/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language": "US English", - "title": "Z2B Chapter 12", - "header": "Chapter 12: Working with Events", - "titleBar": "Zero to Blockchain Tutorial", - "idx_unified": "load Unified User Experience", - "idx_buyer": "load Buyer User Experience", - "idx_seller": "load Seller User Experience", - "idx_provider": "load Provider User Experience", - "idx_shipper": "load Shipper User Experience", - "idx_financeco": "load Finance Company User Experience", - "idx_roles": "Roles", - "idx_admin": "Admin", - "idx_adminUX": "load Admin User Experience", - "idx_preload": "Preload Network" - }, - "admin": { - "title": "Zero To Blockchain Chapter12", - "npm": "Network Profile Management", - "npm_API": "API", - "npm_param": "Parameters", - "npm_dp_api": "delete profile", - "npm_dp_param": "profile name", - "npm_cp_api": "create Profile", - "npm_cp_param": "profile object", - "npm_ga_api": "get all connection profiles", - "npm_ga_param": "(none)", - "npm_g1_api": "get a specific network connection profile", - "npm_g1_param": "profile name", - "bnm": "Business Network Management", - "bnm_param": "Parameters", - "bnm_api": "API", - "bnm_nd_api": "deploy a network", - "bnm_nd_param": "network archive file, options", - "bnm_ni_api": "install new a network", - "bnm_ni_param": "network archive file, options", - "bnm_ns_api": "start an installed network", - "bnm_ns_param": "network name, options", - "bnm_nl_api": "list the deployed business networks", - "bnm_nl_param": "(none)", - "bnm_np_api": "touch a network, check compatibility", - "bnm_np_param": "business network name", - "bnm_nu_api": "take a business network off line", - "bnm_nu_param": "business network name<", - "bnm_nuu_api": "update an existing business network", - "bnm_nuu_param": "business network name, archive file", - "rm": "Resource Management", - "rm_api": "API", - "rm_param": "Parameters", - "rm_lr_api": "list members of a registry", - "rm_la_api": "List Assets in the registry", - "rm_la_param": "(none)", - "rm_am_api": "Add Member", - "rm_am_param": "Co Name, id, Type", - "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", - "bc": "BlockChain", - "bc_api": "API", - "bc_param": "Parameters", - "bc_gi_api": "initiate connection to blockchain", - "bc_gi_param": "(none)", - "bc_ge_api": "register for blockchain events", - "bc_ge_param": "(none)", - "bc_gh_api": "get Historian", - "bc_gh_param": "(none)" - }, - "buyer": { - "title": "Buyer Chapter 12. Select Buyer to see their view: ", - "newOrder": "Create New Order", - "orderStatus": "Display Order Status" - }, - "createConnectionProfile": { - "title": "type the name of the new profile here: ", - "cp_type": "type", - "cp_orderers": "orderers", - "cp_orderers_url": "url", - "cp_ca": "ca", - "cp_ca_url": "url", - "cp_ca_name": "name", - "cp_peers": "peers", - "cp_peers_event_url": "eventURL", - "cp_peers_request_url": "requestURL", - "cp_keyValStore": "keyValStore", - "cp_channel": "channel", - "cp_mspID": "mspID", - "cp_timeout": "timeout", - "cancel": "Cancel", - "submit": "Submit" - }, - "createMember": { - "cd_type": "Type", - "cd_buyer": "Buyer", - "cd_seller": "Seller", - "cd_shipper": "Shipper", - "cd_provider": "Provider", - "cd_financeco": "FinanceCo", - "cd_cn": "Company Name", - "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "createOrder": { - "title": "Create New Order", - "selectVendor": "Select Vendor: ", - "cn_on": "Order Number", - "cn_status": "Status", - "cn_date": "Date", - "cn_total": "Total", - "cn_selectItem": "Select Item", - "addItem": "Add Item", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" - }, - "deleteConnectionProfile": { - "title": "Select Profile to delete: ", - "cancel": "Cancel", - "submit": "Submit" - }, - "financeCo": { - "title": "Zero To Blockchain Chapter 12: The Global Financier", - "financeCOclear": "Clear Window", - "financeCOorderStatus": "Display Order Status" - }, - "getMemberSecret": { - "gs_type": "Type", - "gs_members": "Members", - "gs_company": "Company Name", - "gs_email": "email Address", - "gs_userID": "userID", - "gs_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "provider": { - "title": "Provider Chapter 12, Select Provider to see their view: ", - "provider_clear": "Clear Window", - "providerOrderStatus": "Display Order Status" - }, - "removeMember": { - "rm_type": "Type", - "rm_members": "Members", - "rm_company": "Company Name", - "rm_email": "email Address", - "rm_userID": "userID", - "rm_secret": "secret", - "cancel": "Cancel", - "submit": "Submit" - }, - "seller": { - "title": "Seller Chapter 12, Select Seller to see their view: ", - "seller_clear": "Clear Window", - "sellerOrderStatus": "Display Order Status" - }, - "shipper": { - "title": "Shipper Chapter 12, Select Shipper to see their view: ", - "shipper_clear": "Clear Window", - "shipperOrderStatus": "Display Order Status " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AuthorizePayment", "message": "Authorize Payment"}, - "Dispute": {"select": "Dispute", "message": "Dispute", "prompt": "Reason for Dispute: "}, - "Resolve": {"select": "Resolve", "message": "Resolve", "prompt": "Reason for Resolution: "}, - "Purchase": {"select": "Purchase", "message": "Purchase"}, - "Cancel": {"select": "Cancel", "message": "Cancel"}, - "Pay": {"select": "Pay", "message": "Pay"}, - "RequestShipping": {"select": "Request Shipping", "message": "Request Shipping"}, - "BackOrder": {"select": "BackOrder", "message": "BackOrder", "prompt": "Reason for Backorder: "}, - "PayRequest": {"select": "PayRequest", "message": "Request Payment"}, - "Refund": {"select": "Refund", "message": "Refund", "prompt": "Reason to Resolve or Refund: "}, - "Delivered": {"select": "Delivered", "message": "Delivered"}, - "Delivering": {"select": "Delivering", "message": "Update Delivery Status", "prompt": "Delivery Status: "}, - "Order": {"select": "Order", "message": "Order From Supplier"}, - "NoAction": {"select": "NoAction", "message": "Take No Action"}, - "ex_button": "Execute", - "ca_button": "Cancel", - "orderno": "Order #", - "status": "Status", - "total": "Total", - "seller": "Seller: ", - "itemno": "Item Number", - "description": "Description", - "qty": "Quantity", - "price": "Price", - "processing_msg": "Processing {0} request for order number: {1}", - "b_no_order_msg": "No orders for this buyer: ", - "s_no_order_msg": "No orders for this seller: ", - "p_no_order_msg": "No orders for this provider: ", - "sh_no_order_msg": "No orders for this shipper: ", - "create_msg": "Processing Create Order request", - "buyer": "Buyer: " - }, - "financeCoOrder": { - "status": "Current Status: ", - "action": "Action", - "by": "By", - "date": "Date", - "comments": "Comments", - "created": "Created", - "cancelled": "Cancelled?", - "notCancel": "(not Cancelled)", - "purchased": "Purchased", - "noPurchase": "(no Purchase Request)", - "thirdParty": "3rd Party Order", - "nothirdParty": "(not yet sent to 3rd Party)", - "backordered": "Backordered?", - "notBackordered": "(not Backordered)", - "shippingRequested": "Shipping Requested", - "noRequestShip": "(No Request to Shipper)", - "shippingStarted": "Shipping Started", - "noDeliveryStart": "(Delivery not Started)", - "delivered": "Delivered", - "notDelivered": "(not yet Delivered)", - "payRequested": "Payment Requested", - "noRequest": "(no request for payment)", - "disputed": "Dispute Raised", - "noDispute": "(not in Dispute)" - } -} + "index": {"language":"US English", + "title":"Z2B Chapter 12", + "header":"Chapter 12: Working with Events", + "titleBar":"Zero to Blockchain Tutorial", + "idx_unified":"load Unified User Experience", + "idx_buyer":"load Buyer User Experience", + "idx_seller":"load Seller User Experience", + "idx_provider":"load Provider User Experience", + "idx_shipper":"load Shipper User Experience", + "idx_financeco":"load Finance Company User Experience", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"load Admin User Experience", + "idx_preload":"Preload Network" + }, + "admin": { + "title":"Zero To Blockchain Chapter 05", + "npm":"Network Profile Management", + "npm_API":"API", + "npm_param":"Parameters", + "npm_dp_api":"delete profile", + "npm_dp_param":"profile name", + "npm_cp_api":"create Profile", + "npm_cp_param":"profile object", + "npm_ga_api":"get all connection profiles", + "npm_ga_param":"(none)", + "npm_g1_api":"get a specific network connection profile", + "npm_g1_param":"profile name", + "bnm":"Business Network Management", + "bnm_param":"Parameters", + "bnm_api":"API", + "bnm_nd_api":"deploy a network", + "bnm_nd_param":"network archive file, options", + "bnm_ni_api":"install new a network", + "bnm_ni_param":"network archive file, options", + "bnm_ns_api":"start an installed network", + "bnm_ns_param":"network name, options", + "bnm_nl_api":"list the deployed business networks", + "bnm_nl_param":"(none)", + "bnm_np_api":"touch a network, check compatibility", + "bnm_np_param":"business network name", + "bnm_nu_api":"take a business network off line", + "bnm_nu_param":"business network name<", + "bnm_nuu_api":"update an existing business network", + "bnm_nuu_param":"business network name, archive file", + "rm":"Resource Management", + "rm_api":"API", + "rm_param":"Parameters", + "rm_lr_api":"list members of a registry", + "rm_la_api":"List Assets in the registry", + "rm_la_param":"(none)", + "rm_am_api":"Add Member", + "rm_am_param":"Co Name, id, Type", + "rm_rm_api":"Remove Member", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parameters", + "bc_gi_api":"initiate connection to blockchain", + "bc_gi_param":"(none)", + "bc_ge_api":"register for blockchain events", + "bc_ge_param":"(none)", + "bc_gh_api":"get Historian", + "bc_gh_param":"(none)" + }, + "buyer": { + "title":"Buyer Chapter 06. Select Buyer to see their view: ", + "newOrder":"Create New Order", + "orderStatus":"Display Order Status" + }, + "createConnectionProfile": { + "title":"type the name of the new profile here: ", + "cp_type":"type", + "cp_orderers":"orderers", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"name", + "cp_peers":"peers", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"channel", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Cancel", + "submit":"Submit" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Buyer", + "cd_seller":"Seller", + "cd_shipper":"Shipper", + "cd_provider":"Provider", + "cd_financeco":"FinanceCo", + "cd_cn":"Company Name", + "cd_e":"email Address", + "cancel":"Cancel", + "submit":"Submit" + }, + "createOrder": { + "title":"Create New Order", + "selectVendor":"Select Vendor: ", + "cn_on":"Order Number", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Select Item", + "addItem":"Add Item", + "cancelNewOrder":"Cancel", + "submitNewOrder":"Submit" + }, + "deleteConnectionProfile": { + "title":"Select Profile to delete: ", + "cancel":"Cancel", + "submit":"Submit" + }, + "financeCo": { + "title":"Zero To Blockchain Chapter 10: The Global Financier", + "financeCOclear":"Clear Window", + "financeCOorderStatus":"Display Order Status" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Members", + "gs_company":"Company Name", + "gs_email":"email Address", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "provider": { + "title":"Provider Chapter 08, Select Provider to see their view: ", + "provider_clear":"Clear Window", + "providerOrderStatus":"Display Order Status" + }, + "removeMember": { + "rm_type":"Type", + "rm_members":"Members", + "rm_company":"Company Name", + "rm_email":"email Address", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancel", + "submit":"Submit" + }, + "seller": { + "title":"Seller Chapter 07, Select Seller to see their view: ", + "seller_clear":"Clear Window", + "sellerOrderStatus":"Display Order Status" + }, + "shipper": { + "title":"Shipper Chapter 09, Select Shipper to see their view: ", + "shipper_clear":"Clear Window", + "shipperOrderStatus":"Display Order Status " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AuthorizePayment","message":"Authorize Payment"}, + "Dispute": {"select": "Dispute","message":"Dispute"}, + "Resolve": {"select": "Resolve","message":"Resolve"}, + "Purchase": {"select": "Purchase","message":"Purchase"}, + "Cancel": {"select": "Cancel","message":"Cancel"}, + "Pay": {"select": "Pay","message":"Pay"}, + "RequestShipping": {"select": "Request Shipping","message":"Request Shipping"}, + "BackOrder": {"select": "BackOrder","message":"BackOrder"}, + "PayRequest": {"select": "PayRequest","message":"Request Payment"}, + "Refund": {"select": "Refund","message":"Refund"}, + "Delivered": {"select": "Delivered","message":"Delivered"}, + "Delivering": {"select": "Delivering","message":"Update Delivery Status"}, + "Order": {"select": "Order","message":"Order From Supplier"}, + "NoAction": {"select": "NoAction","message":"Take No Action"}, + "ex_button":"Execute", + "ca_button":"Cancel", + "orderno":"Order #", + "status":"Status", + "total":"Total", + "seller":"Seller: ", + "itemno":"Item Number", + "description":"Description", + "qty":"Quantity", + "price":"Price", + "processing_msg":"Processing {0} request for order number: {1}", + "b_no_order_msg":"No orders for this buyer: ", + "s_no_order_msg":"No orders for this seller: ", + "p_no_order_msg":"No orders for this provider: ", + "sh_no_order_msg":"No orders for this shipper: ", + "create_msg":"Processing Create Order request", + "buyer":"Buyer: " + }, + "financeCoOrder": { + "status":"Current Status: ", + "action":"Action", + "by":"By", + "date":"Date", + "comments":"Comments", + "created":"Created", + "cancelled":"Cancelled?", + "notCancel":"(not Cancelled)", + "purchased":"Purchased", + "noPurchase":"(no Purchase Request)", + "thirdParty":"3rd Party Order", + "nothirdParty":"(not yet sent to 3rd Party)", + "backordered":"Backordered?", + "notBackordered":"(not Backordered)", + "shippingRequested":"Shipping Requested", + "noRequestShip":"(No Request to Shipper)", + "shippingStarted":"Shipping Started", + "noDeliveryStart":"(Delivery not Started)", + "delivered":"Delivered", + "notDelivered":"(not yet Delivered)", + "payRequested":"Payment Requested", + "noRequest":"(no request for payment)", + "disputed":"Dispute Raised", + "noDispute":"(not in Dispute)" + } + } \ No newline at end of file diff --git a/Chapter12/controller/restapi/features/text/en-US/prompts.json b/Chapter12/controller/restapi/features/text/en-US/prompts.json index e9943a9..a519da2 100644 --- a/Chapter12/controller/restapi/features/text/en-US/prompts.json +++ b/Chapter12/controller/restapi/features/text/en-US/prompts.json @@ -53,7 +53,10 @@ "rm_am_api": "Add Member", "rm_am_param": "Co Name, id, Type", "rm_rm_api": "Remove Member", - "rm_gs_api": "getMemberSecret", + "rm_gs_api": "get Member Secret", + "rm_ii_api": "Issue Identity", + "rm_cc_api": "Check if card exists", + "rm_cc2_api": "Create Card", "bc": "BlockChain", "bc_api": "API", "bc_param": "Parameters", @@ -96,8 +99,8 @@ "cd_financeco": "FinanceCo", "cd_cn": "Company Name", "cd_e": "email Address", - "cancelNewOrder": "Cancel", - "submitNewOrder": "Submit" + "cancel": "Cancel", + "submit": "Submit" }, "createOrder": { "title": "Create New Order", diff --git a/Chapter12/controller/restapi/features/text/es-LA/prompts.json b/Chapter12/controller/restapi/features/text/es-LA/prompts.json index a6aeed2..04b9936 100644 --- a/Chapter12/controller/restapi/features/text/es-LA/prompts.json +++ b/Chapter12/controller/restapi/features/text/es-LA/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"LA Español", - "title":"Z2B Capítulo 12", - "header":"Capítulo 12; Trabajando con eventos", - "titleBar":"Cero al tutorial de Blockchain", - "idx_unified":"Cargar experiencia de usuario unificada", - "idx_buyer":"Cargar la experiencia del usuario del comprador", - "idx_seller":"Cargar experiencia de usuario del vendedor", - "idx_provider":"Cargar experiencia de usuario del proveedor", - "idx_shipper":"Cargar experiencia de usuario del transportista", - "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", - "idx_roles":"Roles", - "idx_admin":"Administrador", - "idx_adminUX":"Cargar experiencia de usuario del administrador", - "idx_preload":"Precardar red" - }, - "admin": { - "title":"Cero al tutorial de Blockchain Capítulo 05", - "npm":"Administración del perfil de redes", - "npm_API":"API", - "npm_param":"Parámetros", - "npm_dp_api":"borrar perfil", - "npm_dp_param":"nombre del perfil ", - "npm_cp_api":"crear perfil", - "npm_cp_param":"objeto de perfil", - "npm_ga_api":"obtener todos los perfiles de conexión", - "npm_ga_param":"(ninguno)", - "npm_g1_api":"conseguor un perfil de red de conexión espécífico", - "npm_g1_param":"nombre del perfil ", - "bnm":"Administrador de red de negocios", - "bnm_param":"Parámetros", - "bnm_api":"API", - "bnm_nd_api":"desplegar una red", - "bnm_nd_param":"archivo de red, opciones", - "bnm_ni_api":"instalar una nueva red", - "bnm_ni_param":"archivo de red, opciones", - "bnm_ns_api":"iniciar una red instalada", - "bnm_ns_param":"nombre de la red, opciones", - "bnm_nl_api":"enumerar las redes empresariales desplegadas", - "bnm_nl_param":"(ninguna)", - "bnm_np_api":"toca una red, comprueba la compatibilidad", - "bnm_np_param":"nombre de la red comercial", - "bnm_nu_api":"tomar una red de negocios fuera de línea", - "bnm_nu_param":"nombre de la red comercial <", - "bnm_nuu_api":"actualizar una red comercial existente", - "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", - "rm":"Administracion de recursos", - "rm_api":"API", - "rm_param":"Parámetros", - "rm_lr_api":"listar miembros de un registro", - "rm_la_api":"Lista de activos en el registro", - "rm_la_param":"(ninguna)", - "rm_am_api":"Añadir miembro", - "rm_am_param":"Co Nombre, id, Tipo", - "rm_rm_api":"Eliminar miembro", - "rm_gs_api":"obtenerMiembroSecreto", - "bc":"BlockChain", - "bc_api":"API", - "bc_param":"Parámetros", - "bc_gi_api":"iniciar la conexión a blockchain", - "bc_gi_param":"(ninguna)", - "bc_ge_api":"registrarse para eventos blockchain", - "bc_ge_param":"(ninguna)", - "bc_gh_api":"obtener un historiador", - "bc_gh_param":"(ninguna)" - }, - "buyer": { - "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", - "newOrder":"Crear nuevo orden", - "orderStatus":"Mostrar estado del pedido" - }, - "createConnectionProfile": { - "title":"tipo de nombre para un nuevo perfil aquí:", - "cp_type":"tipo", - "cp_orderers":"solicitantes", - "cp_orderers_url":"Localizador Uniforme de Recursos (url)", - "cp_ca":"ca", - "cp_ca_url":"Localizador Uniforme de Recursos (url)", - "cp_ca_name":"nombre", - "cp_peers":"semejantes", - "cp_peers_event_url":"eventoURL", - "cp_peers_request_url":"requerirURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"tiempofuera", - "cancel":"Cancelar", - "submit":"Someter" - }, - "createMember": { - "cd_type":"Tipo", - "cd_buyer":"Comprador", - "cd_seller":"Vendedor", - "cd_shipper":"Expedidor", - "cd_provider":"Proveedor", - "cd_financeco":"Compañía financiera", - "cd_cn":"nombre de empresa", - "cd_e":"dirección de correo electrónico", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "createOrder": { - "title":"Crear nueva orden", - "selectVendor":"Seleccionar proveedor:", - "cn_on":"Número de orden", - "cn_status":"Estado", - "cn_date":"Fecha", - "cn_total":"Total", - "cn_selectItem":"Seleccione un artículo", - "addItem":"Añadir artículo", - "cancelNewOrder":"Cancelar", - "submitNewOrder":"Enviar" - }, - "deleteConnectionProfile": { - "title":"Seleccionar perfil para eliminar:", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "financeCo": { - "title":"Cero a Blockchain Capítulo 10: El financiero global", - "financeCOclear":"Ventana limpia", - "financeCOorderStatus":"Mostrar estado del pedido" - }, - "getMemberSecret": { - "gs_type":"Tipo", - "gs_members":"Miembros", - "gs_company":"nombre de empresa", - "gs_email":"dirección de correo electrónico", - "gs_userID":"identidad de usuario", - "gs_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "provider": { - "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", - "provider_clear":"Ventana limpia", - "providerOrderStatus":"Mostrar estado del pedido" - }, - "removeMember": { - "rm_type":"Tipo", - "rm_members":"Miembros", - "rm_company":"nombre de empresa", - "rm_email":"dirección de correo electrónico", - "rm_userID":"identidad de usuario", - "rm_secret":"secreto", - "cancel":"Cancelar", - "submit":"Enviar" - }, - "seller": { - "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", - "seller_clear":"Ventana limpia", - "sellerOrderStatus":"Mostrar estado del pedido" - }, - "shipper": { - "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", - "shipper_clear":"Ventana limpia", - "shipperOrderStatus":"Mostrar estado del pedido" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, - "Dispute": {"select": "Disputa","message":"Disputa"}, - "Resolve": {"select": "Resolver","message":"Resolver"}, - "Purchase": {"select": "Compra","message":"Compra"}, - "Cancel": {"select": "Cancelar","message":"Cancelar"}, - "Pay": {"select": "Paga","message":"Paga"}, - "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, - "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, - "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, - "Refund": {"select": "Reembolso","message":"Reembolso"}, - "Delivered": {"select": "Entregado","message":"Entregado"}, - "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, - "Order": {"select": "Orden","message":"Ordene del proveedor"}, - "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, - "ex_button":"Ejecutar", - "ca_button":"Cancelar", - "orderno":"Orden #", - "status":"Estado", - "total":"Total", - "seller":"Vendedor:", - "itemno":"Número de artículo", - "description":"Descripción", - "qty":"Cantidad", - "price":"Precio", - "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", - "b_no_order_msg":"No hay pedidos para este comprador:", - "s_no_order_msg":"No hay pedidos para este vendedor:", - "p_no_order_msg":"No hay pedidos para este proveedor:", - "sh_no_order_msg":"No hay pedidos para este remitente:", - "create_msg":"Procesando Crear solicitud de pedido", - "buyer":"Comprador:" - }, - "financeCoOrder": { - "status":"Estatus actual", - "action":"Acción", - "by":"Por", - "date":"Fecha", - "comments":"Comentarios", - "created":"Creado", - "cancelled":"Cancelado", - "notCancel":"(no cancelado)", - "purchased":"Comprado", - "noPurchase":"(no hay orden de compra)", - "thirdParty":"Orden de un tercero", - "nothirdParty":"(no se ha enviado a un tercero)", - "backordered":"¿Atrasado?", - "notBackordered":"(no atrasado)", - "shippingRequested":"Embarque requerido", - "noRequestShip":"(No hay requerimiento al transportista)", - "shippingStarted":"Embarque iniciado", - "noDeliveryStart":"(No ha comenzado la entrega)", - "delivered":"Entregado", - "notDelivered":"(no ha sido entregado)", - "payRequested":"Pago requerido", - "noRequest":"(no se ha solicitado el pago)", - "disputed":"Disputa planteada", - "noDispute":"(no en disputa)" - } - } \ No newline at end of file + "index": {"language":"LA Español", + "title":"Z2B Capítulo 12", + "header":"Capítulo 12; Trabajando con eventos", + "titleBar":"Cero al tutorial de Blockchain", + "idx_unified":"Cargar experiencia de usuario unificada", + "idx_buyer":"Cargar la experiencia del usuario del comprador", + "idx_seller":"Cargar experiencia de usuario del vendedor", + "idx_provider":"Cargar experiencia de usuario del proveedor", + "idx_shipper":"Cargar experiencia de usuario del transportista", + "idx_financeco":"Cargar experiencia de usuario de la compañía financiera", + "idx_roles":"Roles", + "idx_admin":"Administrador", + "idx_adminUX":"Cargar experiencia de usuario del administrador", + "idx_preload":"Precardar red" + }, + "admin": { + "title":"Cero al tutorial de Blockchain Capítulo 05", + "npm":"Administración del perfil de redes", + "npm_API":"API", + "npm_param":"Parámetros", + "npm_dp_api":"borrar perfil", + "npm_dp_param":"nombre del perfil ", + "npm_cp_api":"crear perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obtener todos los perfiles de conexión", + "npm_ga_param":"(ninguno)", + "npm_g1_api":"conseguor un perfil de red de conexión espécífico", + "npm_g1_param":"nombre del perfil ", + "bnm":"Administrador de red de negocios", + "bnm_param":"Parámetros", + "bnm_api":"API", + "bnm_nd_api":"desplegar una red", + "bnm_nd_param":"archivo de red, opciones", + "bnm_ni_api":"instalar una nueva red", + "bnm_ni_param":"archivo de red, opciones", + "bnm_ns_api":"iniciar una red instalada", + "bnm_ns_param":"nombre de la red, opciones", + "bnm_nl_api":"enumerar las redes empresariales desplegadas", + "bnm_nl_param":"(ninguna)", + "bnm_np_api":"toca una red, comprueba la compatibilidad", + "bnm_np_param":"nombre de la red comercial", + "bnm_nu_api":"tomar una red de negocios fuera de línea", + "bnm_nu_param":"nombre de la red comercial <", + "bnm_nuu_api":"actualizar una red comercial existente", + "bnm_nuu_param":"nombre de la red comercial, archivo de almacenamiento", + "rm":"Administracion de recursos", + "rm_api":"API", + "rm_param":"Parámetros", + "rm_lr_api":"listar miembros de un registro", + "rm_la_api":"Lista de activos en el registro", + "rm_la_param":"(ninguna)", + "rm_am_api":"Añadir miembro", + "rm_am_param":"Co Nombre, id, Tipo", + "rm_rm_api":"Eliminar miembro", + "rm_gs_api":"obtenerMiembroSecreto", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"verificar si existe una tarjeta de identidad", + "rm_cc2_api": "crear una tarjeta de identidad", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parámetros", + "bc_gi_api":"iniciar la conexión a blockchain", + "bc_gi_param":"(ninguna)", + "bc_ge_api":"registrarse para eventos blockchain", + "bc_ge_param":"(ninguna)", + "bc_gh_api":"obtener un historiador", + "bc_gh_param":"(ninguna)" + }, + "buyer": { + "title":"Comprador Capítulo 06. Seleccione Comprador para ver su vista:", + "newOrder":"Crear nuevo orden", + "orderStatus":"Mostrar estado del pedido" + }, + "createConnectionProfile": { + "title":"tipo de nombre para un nuevo perfil aquí:", + "cp_type":"tipo", + "cp_orderers":"solicitantes", + "cp_orderers_url":"Localizador Uniforme de Recursos (url)", + "cp_ca":"ca", + "cp_ca_url":"Localizador Uniforme de Recursos (url)", + "cp_ca_name":"nombre", + "cp_peers":"semejantes", + "cp_peers_event_url":"eventoURL", + "cp_peers_request_url":"requerirURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"tiempofuera", + "cancel":"Cancelar", + "submit":"Someter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Comprador", + "cd_seller":"Vendedor", + "cd_shipper":"Expedidor", + "cd_provider":"Proveedor", + "cd_financeco":"Compañía financiera", + "cd_cn":"nombre de empresa", + "cd_e":"dirección de correo electrónico", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "createOrder": { + "title":"Crear nueva orden", + "selectVendor":"Seleccionar proveedor:", + "cn_on":"Número de orden", + "cn_status":"Estado", + "cn_date":"Fecha", + "cn_total":"Total", + "cn_selectItem":"Seleccione un artículo", + "addItem":"Añadir artículo", + "cancelNewOrder":"Cancelar", + "submitNewOrder":"Enviar" + }, + "deleteConnectionProfile": { + "title":"Seleccionar perfil para eliminar:", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "financeCo": { + "title":"Cero a Blockchain Capítulo 10: El financiero global", + "financeCOclear":"Ventana limpia", + "financeCOorderStatus":"Mostrar estado del pedido" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Miembros", + "gs_company":"nombre de empresa", + "gs_email":"dirección de correo electrónico", + "gs_userID":"identidad de usuario", + "gs_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "provider": { + "title":"Proveedor Capítulo 08, Seleccione Proveedor para ver su vista:", + "provider_clear":"Ventana limpia", + "providerOrderStatus":"Mostrar estado del pedido" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Miembros", + "rm_company":"nombre de empresa", + "rm_email":"dirección de correo electrónico", + "rm_userID":"identidad de usuario", + "rm_secret":"secreto", + "cancel":"Cancelar", + "submit":"Enviar" + }, + "seller": { + "title":"Vendedor Capítulo 07, Seleccione Vendedor para ver su vista:", + "seller_clear":"Ventana limpia", + "sellerOrderStatus":"Mostrar estado del pedido" + }, + "shipper": { + "title":"Remitente Capítulo 09, seleccione Transportista para ver su vista:", + "shipper_clear":"Ventana limpia", + "shipperOrderStatus":"Mostrar estado del pedido" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar pago","message":"Autorizar el pago"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Paga","message":"Paga"}, + "RequestShipping": {"select": "Solicitud de envío","message":"Solicitud de envío"}, + "BackOrder": {"select": "OrdenAtrasada","message":"Orden atrasada"}, + "PayRequest": {"select": "Requerimiento de pago","message":"Solicitar pago"}, + "Refund": {"select": "Reembolso","message":"Reembolso"}, + "Delivered": {"select": "Entregado","message":"Entregado"}, + "Delivering": {"select": "Entregando","message":"Actualizar el estado de entrega"}, + "Order": {"select": "Orden","message":"Ordene del proveedor"}, + "NoAction": {"select": "NoAcción","message":"No tomar ninguna medida"}, + "ex_button":"Ejecutar", + "ca_button":"Cancelar", + "orderno":"Orden #", + "status":"Estado", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Número de artículo", + "description":"Descripción", + "qty":"Cantidad", + "price":"Precio", + "processing_msg":"Procesando {0} solicitud de número de pedido: {1}", + "b_no_order_msg":"No hay pedidos para este comprador:", + "s_no_order_msg":"No hay pedidos para este vendedor:", + "p_no_order_msg":"No hay pedidos para este proveedor:", + "sh_no_order_msg":"No hay pedidos para este remitente:", + "create_msg":"Procesando Crear solicitud de pedido", + "buyer":"Comprador:" + }, + "financeCoOrder": { + "status":"Estatus actual", + "action":"Acción", + "by":"Por", + "date":"Fecha", + "comments":"Comentarios", + "created":"Creado", + "cancelled":"Cancelado", + "notCancel":"(no cancelado)", + "purchased":"Comprado", + "noPurchase":"(no hay orden de compra)", + "thirdParty":"Orden de un tercero", + "nothirdParty":"(no se ha enviado a un tercero)", + "backordered":"¿Atrasado?", + "notBackordered":"(no atrasado)", + "shippingRequested":"Embarque requerido", + "noRequestShip":"(No hay requerimiento al transportista)", + "shippingStarted":"Embarque iniciado", + "noDeliveryStart":"(No ha comenzado la entrega)", + "delivered":"Entregado", + "notDelivered":"(no ha sido entregado)", + "payRequested":"Pago requerido", + "noRequest":"(no se ha solicitado el pago)", + "disputed":"Disputa planteada", + "noDispute":"(no en disputa)" + } + } \ No newline at end of file diff --git a/Chapter12/controller/restapi/features/text/fr/prompts.json b/Chapter12/controller/restapi/features/text/fr/prompts.json index 5df0155..cd5b49d 100644 --- a/Chapter12/controller/restapi/features/text/fr/prompts.json +++ b/Chapter12/controller/restapi/features/text/fr/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"Le Français", - "title":"Z2B Chapitre 12", - "header":"Chapitre 12 : Intégrer les vues utilisateur", - "titleBar":"Zero to Blockchain tutoriel", - "idx_unified":"Charger l'expérience utilisateur unifiée", - "idx_buyer":"Charger l'expérience de l'acheteur", - "idx_seller":"Charger l'expérience du vendeur", - "idx_provider":"Charger l'expérience du fournisseur", - "idx_shipper":"Charger l'expérience de lexpéditeur", - "idx_financeco":"Charger l'expérience du financier", - "idx_roles":"Roles", - "idx_admin":"Admin", - "idx_adminUX":"Charger l'expérience de l'administrateur", - "idx_preload":"Pré-charger le Réseau" - }, - "admin": { - "title":"Zero to Blockchain Chapitre 05", - "npm":"Gestion profil réseau", - "npm_API":"API", - "npm_param":"Paramètres", - "npm_dp_api":"Effacer le profil", - "npm_dp_param":"Nom du profil", - "npm_cp_api":"Créer un profil", - "npm_cp_param":"Objet du Profil", - "npm_ga_api":"Obtenir tous les profils de connexion", - "npm_ga_param":"(aucun)", - "npm_g1_api":"Obyenir un profil de connexion spécifique", - "npm_g1_param":"Nom du profil", - "bnm":"Gestion du Réseau d'affaire", - "bnm_param":"Paramètres", - "bnm_api":"API", - "bnm_nd_api":"Déployer un réseau", - "bnm_nd_param":"Fichier archive réseau, options", - "bnm_ni_api":"Installer un nouveau réseau", - "bnm_ni_param":"Fichier archive réseau, options", - "bnm_ns_api":"Démarrer un réseau installé", - "bnm_ns_param":"Nom du réseau, options", - "bnm_nl_api":"Liste des réseaux d'affaire déployés", - "bnm_nl_param":"(aucun)", - "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", - "bnm_np_param":"Nom du réseau d'affaire", - "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", - "bnm_nu_param":"Nom du réseau d'affaire<", - "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", - "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", - "rm":"Gestion des ressources", - "rm_api":"API", - "rm_param":"Paramètres", - "rm_lr_api":"Lister les membres d'un registre", - "rm_la_api":"Lister les objets d'un registre", - "rm_la_param":"(aucun)", - "rm_am_api":"Ajouter un membre", - "rm_am_param":"Co nom, id, type", - "rm_rm_api":"Retirer membre", - "rm_gs_api":"getmembersecret", - "bc":"Blockchain", - "bc_api":"API", - "bc_param":"Paramètres", - "bc_gi_api":"Initier la connexion à Blockchain", - "bc_gi_param":"(aucun)", - "bc_ge_api":"Enregistrer pour les évènements Blockchain", - "bc_ge_param":"(aucun)", - "bc_gh_api":"Charger l'historique", - "bc_gh_param":"(aucun)" - }, - "buyer": { - "title":"Chapitre 12 acheteur. Sélectionner l'acheteur pour voir leur vue:", - "newOrder":"Créér une nouvelle commande", - "orderStatus":"Afficher le status des Commandes" - }, - "createConnectionProfile": { - "title":"Entrer le nom du nouveau profil ici:", - "cp_type":"type", - "cp_orderers":"Commandes", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"nom", - "cp_peers":"pairs", - "cp_peers_event_url":"eventURL", - "cp_peers_request_url":"requestURL", - "cp_keyValStore":"keyValStore", - "cp_channel":"canal", - "cp_mspID":"mspID", - "cp_timeout":"timeout", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "createMember": { - "cd_type":"Type", - "cd_buyer":"Acheteur", - "cd_seller":"Vendeur", - "cd_shipper":"Expéditeur", - "cd_provider":"Fournisseur", - "cd_financeco":"Financeur", - "cd_cn":"Nom Companie", - "cd_e":"Adresse email", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "createOrder": { - "title":"Créér un nouvel ordre", - "selectVendor":"Selectionner fournisseur:", - "cn_on":"Numéro de commande", - "cn_status":"Status", - "cn_date":"Date", - "cn_total":"Total", - "cn_selectItem":"Selectionner item", - "addItem":"Ajouter item", - "cancelNewOrder":"Annuler", - "submitNewOrder":"Soumettre" - }, - "deleteConnectionProfile": { - "title":"Selectionner le profil à annuler", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "financeCo": { - "title":"Zero to Blockchain Chapitre 12: Le financier mondial", - "financeCOclear":"Effacer le contenu de la fenetre", - "financeCOorderStatus":"Afficher le status des Commandes" - }, - "getMemberSecret": { - "gs_type":"Type", - "gs_members":"Membres", - "gs_company":"Nom Companie", - "gs_email":"Adresse email", - "gs_userID":"userID", - "gs_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "provider": { - "title":"Fournisseur Chapitre 12, Sélectionner le fournisseur pour voir sa vue:", - "provider_clear":"Effacer le contenu de la fenetre", - "providerOrderStatus":"Afficher le status des Commandes" - }, - "removeMember": { - "rm_type":"", - "rm_members":"Type", - "rm_company":"Membres", - "rm_email":"Adresse email", - "rm_userID":"userID", - "rm_secret":"secret", - "cancel":"Annuler", - "submit":"Soumettre" - }, - "seller": { - "title":"Vendeur Chapitre 12, Selectionner le Vendeur pour voir sa vue:", - "seller_clear":"Effacer le contenu de la fenetre", - "sellerOrderStatus":"Afficher le status des Commandes" - }, - "shipper": { - "title":"Expéditeur Chapitre 12, Sélectionner l'expéditeur pour voir sa vue:", - "shipper_clear":"Effacer le contenu de la fenetre", - "shipperOrderStatus":"Afficher le status des Commandes" - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, - "Dispute": {"select": "Disputer","message":"Dispute"}, - "Resolve": {"select": "Résoudre","message":"Résoudre"}, - "Purchase": {"select": "Acheter","message":"Acheter"}, - "Cancel": {"select": "Annuler","message":"Annuler"}, - "Pay": {"select": "Payer","message":"Payer"}, - "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, - "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, - "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, - "Refund": {"select": "Remboursement","message":"Rembourser"}, - "Delivered": {"select": "Livré","message":"Livré"}, - "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, - "Order": {"select": "Commande","message":"Commande du fournisseur"}, - "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, - "ex_button":"Ecécuter", - "ca_button":"Annuler", - "orderno":"# Commande", - "status":"Status", - "total":"Total", - "seller":"Vendeur:", - "itemno":"Numero item", - "description":"Description", - "qty":"Quantité", - "price":"Prix", - "processing_msg":"Processer(0) demander le numero de commande:(1)", - "b_no_order_msg":"Pas de commande pour cet acheteur:", - "s_no_order_msg":"Pas de commande pour ce vendeur:", - "p_no_order_msg":"Pas de commande pour ce fournisseur:", - "sh_no_order_msg":"Pas de commande pour cet expéditeur:", - "create_msg":"Création demande de commande en cours", - "buyer":"Acheteur:" - }, - "financeCoOrder": { - "status":"Status actuel:", - "action":"Action", - "by":"Par", - "date":"Date", - "comments":"Commentaires", - "created":"Créé", - "cancelled":"Annulé?", - "notCancel":"(non annulé)", - "purchased":"Acheté", - "noPurchase":"(pas de demande de commande)", - "thirdParty":"Commande de partie tierce", - "nothirdParty":"(pas encire envoyé à partie tierce)", - "backordered":"Rupture de stock?", - "notBackordered":"(pas de rupture de stock)", - "shippingRequested":"Expédition demandée", - "noRequestShip":"(pas de demande à l'expéditeur)", - "shippingStarted":"Expédition en cours", - "noDeliveryStart":"(expédition en attente)", - "delivered":"Livré", - "notDelivered":"(pas encore livré)", - "payRequested":"Paiement demandé", - "noRequest":"(paiement pas encore demandé)", - "disputed":"Dispute lancée", - "noDispute":"(pas de dispute)" - } - } \ No newline at end of file + "index": {"language":"Anglais USA", + "title":"Z2B Chapitre 12", + "header":"Chapitre 12 : Gérer les évènements", + "titleBar":"Zero to Blockchain tutoriel", + "idx_unified":"Charger l'expérience utilisateur unifiée", + "idx_buyer":"Charger l'expérience de l'acheteur", + "idx_seller":"Charger l'expérience du vendeur", + "idx_provider":"Charger l'expérience du fournisseur", + "idx_shipper":"Charger l'expérience de lexpéditeur", + "idx_financeco":"Charger l'expérience du financier", + "idx_roles":"Roles", + "idx_admin":"Admin", + "idx_adminUX":"Charger l'expérience de l'administrateur", + "idx_preload":"Pré-charger le Réseau" + }, + "admin": { + "title":"Zero to Blockchain Chapitre 05", + "npm":"Gestion profil réseau", + "npm_API":"API", + "npm_param":"Paramètres", + "npm_dp_api":"Effacer le profil", + "npm_dp_param":"Nom du profil", + "npm_cp_api":"Créer un profil", + "npm_cp_param":"Objet du Profil", + "npm_ga_api":"Obtenir tous les profils de connexion", + "npm_ga_param":"(aucun)", + "npm_g1_api":"Obyenir un profil de connexion spécifique", + "npm_g1_param":"Nom du profil", + "bnm":"Gestion du Réseau d'affaire", + "bnm_param":"Paramètres", + "bnm_api":"API", + "bnm_nd_api":"Déployer un réseau", + "bnm_nd_param":"Fichier archive réseau, options", + "bnm_ni_api":"Installer un nouveau réseau", + "bnm_ni_param":"Fichier archive réseau, options", + "bnm_ns_api":"Démarrer un réseau installé", + "bnm_ns_param":"Nom du réseau, options", + "bnm_nl_api":"Liste des réseaux d'affaire déployés", + "bnm_nl_param":"(aucun)", + "bnm_np_api":"Selectionner un réseau, vérifier la compatibilité", + "bnm_np_param":"Nom du réseau d'affaire", + "bnm_nu_api":"Prendre un réseau d'affaire hors ligne", + "bnm_nu_param":"Nom du réseau d'affaire<", + "bnm_nuu_api":"Mettre à jour un réseau d'affaire existant", + "bnm_nuu_param":"Nom du réseau d'affaire, fichier d'archive", + "rm":"Gestion des ressources", + "rm_api":"API", + "rm_param":"Paramètres", + "rm_lr_api":"Lister les membres d'un registre", + "rm_la_api":"Lister les objets d'un registre", + "rm_la_param":"(aucun)", + "rm_am_api":"Ajouter un membre", + "rm_am_param":"Co nom, id, type", + "rm_rm_api":"Retirer membre", + "rm_gs_api":"getmembersecret", + "rm_ii_api":"émission d'identité", + "rm_cc_api":"vérifier si la carte d'identité existe", + "rm_cc2_api": "Créér une nouvelle carte d'identité", + "bc":"Blockchain", + "bc_api":"API", + "bc_param":"Paramètres", + "bc_gi_api":"Initier la connexion à Blockchain", + "bc_gi_param":"(aucun)", + "bc_ge_api":"Enregistrer pour les évènements Blockchain", + "bc_ge_param":"(aucun)", + "bc_gh_api":"Charger l'historique", + "bc_gh_param":"(aucun)" + }, + "buyer": { + "title":"Chapitre 6 acheteur. Sélectionner l'acheteur pour voir leur vue:", + "newOrder":"Créér une nouvelle commande", + "orderStatus":"Afficher le status des Commandes" + }, + "createConnectionProfile": { + "title":"Entrer le nom du nouveau profil ici:", + "cp_type":"type", + "cp_orderers":"Commandes", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nom", + "cp_peers":"pairs", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"timeout", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createMember": { + "cd_type":"Type", + "cd_buyer":"Acheteur", + "cd_seller":"Vendeur", + "cd_shipper":"Expéditeur", + "cd_provider":"Fournisseur", + "cd_financeco":"Financeur", + "cd_cn":"Nom Companie", + "cd_e":"Adresse email", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "createOrder": { + "title":"Créér un nouvel ordre", + "selectVendor":"Selectionner fournisseur:", + "cn_on":"Numéro de commande", + "cn_status":"Status", + "cn_date":"Date", + "cn_total":"Total", + "cn_selectItem":"Selectionner item", + "addItem":"Ajouter item", + "cancelNewOrder":"Annuler", + "submitNewOrder":"Soumettre" + }, + "deleteConnectionProfile": { + "title":"Selectionner le profil à annuler", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "financeCo": { + "title":"Zero to Blockchain Chapitre 10: Le financier mondial", + "financeCOclear":"Effacer le contenu de la fenetre", + "financeCOorderStatus":"Afficher le status des Commandes" + }, + "getMemberSecret": { + "gs_type":"Type", + "gs_members":"Membres", + "gs_company":"Nom Companie", + "gs_email":"Adresse email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "provider": { + "title":"Fournisseur Chapitre 8, Sélectionner le fournisseur pour voir sa vue:", + "provider_clear":"Effacer le contenu de la fenetre", + "providerOrderStatus":"Afficher le status des Commandes" + }, + "removeMember": { + "rm_type":"", + "rm_members":"Type", + "rm_company":"Membres", + "rm_email":"Adresse email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Annuler", + "submit":"Soumettre" + }, + "seller": { + "title":"Vendeur Chapitre 07, Selectionner le Vendeur pour voir sa vue:", + "seller_clear":"Effacer le contenu de la fenetre", + "sellerOrderStatus":"Afficher le status des Commandes" + }, + "shipper": { + "title":"Expéditeur Chapitre 09, Sélectionner l'expéditeur pour voir sa vue:", + "shipper_clear":"Effacer le contenu de la fenetre", + "shipperOrderStatus":"Afficher le status des Commandes" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "AutoriserPaiement","message":"Autoriser le paiement"}, + "Dispute": {"select": "Disputer","message":"Dispute"}, + "Resolve": {"select": "Résoudre","message":"Résoudre"}, + "Purchase": {"select": "Acheter","message":"Acheter"}, + "Cancel": {"select": "Annuler","message":"Annuler"}, + "Pay": {"select": "Payer","message":"Payer"}, + "RequestShipping": {"select": "Demander l'expédition","message":"Demander l'expédition"}, + "BackOrder": {"select": "Rupture de Stock","message":"Rupture de stock"}, + "PayRequest": {"select": "DemandePaiement","message":"Demander le paiement"}, + "Refund": {"select": "Remboursement","message":"Rembourser"}, + "Delivered": {"select": "Livré","message":"Livré"}, + "Delivering": {"select": "En livraison","message":"Mise à jour status de livraison"}, + "Order": {"select": "Commande","message":"Commande du fournisseur"}, + "NoAction": {"select": "Pas d'action","message":"Pas d'action"}, + "ex_button":"Ecécuter", + "ca_button":"Annuler", + "orderno":"# Commande", + "status":"Status", + "total":"Total", + "seller":"Vendeur:", + "itemno":"Numero item", + "description":"Description", + "qty":"Quantité", + "price":"Prix", + "processing_msg":"Processer(0) demander le numero de commande:(1)", + "b_no_order_msg":"Pas de commande pour cet acheteur:", + "s_no_order_msg":"Pas de commande pour ce vendeur:", + "p_no_order_msg":"Pas de commande pour ce fournisseur:", + "sh_no_order_msg":"Pas de commande pour cet expéditeur:", + "create_msg":"Création demande de commande en cours", + "buyer":"Acheteur:" + }, + "financeCoOrder": { + "status":"Status actuel:", + "action":"Action", + "by":"Par", + "date":"Date", + "comments":"Commentaires", + "created":"Créé", + "cancelled":"Annulé?", + "notCancel":"(non annulé)", + "purchased":"Acheté", + "noPurchase":"(pas de demande de commande)", + "thirdParty":"Commande de partie tierce", + "nothirdParty":"(pas encire envoyé à partie tierce)", + "backordered":"Rupture de stock?", + "notBackordered":"(pas de rupture de stock)", + "shippingRequested":"Expédition demandée", + "noRequestShip":"(pas de demande à l'expéditeur)", + "shippingStarted":"Expédition en cours", + "noDeliveryStart":"(expédition en attente)", + "delivered":"Livré", + "notDelivered":"(pas encore livré)", + "payRequested":"Paiement demandé", + "noRequest":"(paiement pas encore demandé)", + "disputed":"Dispute lancée", + "noDispute":"(pas de dispute)" + } + } \ No newline at end of file diff --git a/Chapter12/controller/restapi/features/text/jp/prompts.json b/Chapter12/controller/restapi/features/text/jp/prompts.json index 98edefa..61d2446 100644 --- a/Chapter12/controller/restapi/features/text/jp/prompts.json +++ b/Chapter12/controller/restapi/features/text/jp/prompts.json @@ -1,219 +1,222 @@ { - "index": {"language":"米国英語", - "title":"Z2B 弟 12章", - "header":"弟 12章: ユーザービューの統合", - "titleBar":"Zero to Blockchainチュートリアル", - "idx_unified":"統合ユーザー経験のロード", - "idx_buyer":"購入者ユーザー経験のロード", - "idx_seller":"販売者ユーザー経験のロード", - "idx_provider":"プロバイダユーユーザー経験のロード", - "idx_shipper":"荷送人ユーザー経験のロード", - "idx_financeco":"財務会社ユーザー経験のロード", - "idx_roles":"役割", - "idx_admin":"管理者", - "idx_adminUX":"管理者ユーザー経験のロード", - "idx_preload":"事前ロードネットワーク" - }, - "admin": { - "title":"Zero To Blockchain 弟12章", - "npm":"ネットワークプロファイル管理", - "npm_API":"API", - "npm_param":"パラメーター", - "npm_dp_api":"プロフィールの削除", - "npm_dp_param":"プロフィール名", - "npm_cp_api":"プロフィールの作成", - "npm_cp_param":"プロファイルオブジェクト", - "npm_ga_api":"すべての接続プロファイルの取得", - "npm_ga_param":"(なし)", - "npm_g1_api":"特定のネットワーク接続プロファイルの取得", - "npm_g1_param":"プロフィール名", - "bnm":"ビジネスネットワーク管理", - "bnm_param":"パラメーター", - "bnm_api":"API", - "bnm_nd_api":"ネットワークの展開", - "bnm_nd_param":"ネットワークアーカイブファイル、オプション", - "bnm_ni_api":"新規ネットワークのインストールする", - "bnm_ni_param":"ネットワークアーカイブファイル、オプション", - "bnm_ns_api":"インストールされたネットワークの開始", - "bnm_ns_param":"ネットワーク名、オプション", - "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", - "bnm_nl_param":"(なし)", - "bnm_np_api":"ネットワークに触れる、互換性をチェックする", - "bnm_np_param":"ビジネスネットワーク名", - "bnm_nu_api":"ビジネスネットワークをオフラインにする", - "bnm_nu_param":"ビジネスネットワーク名<", - "bnm_nuu_api":"既存のビジネスネットワークの更新", - "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", - "rm":"リソース管理", - "rm_api":"API", - "rm_param":"パラメーター", - "rm_lr_api":"レジストリのメンバーの一覧表示", - "rm_la_api":"レジストリのリストアセット", - "rm_la_param":"(なし)", - "rm_am_api":"メンバーの追加", - "rm_am_param":"Co 名, id, タイプ", - "rm_rm_api":"メンバーの削除", - "rm_gs_api":"メンバーシークレットの取得", - "bc":"ブロックチェーン", - "bc_api":"API", - "bc_param":"パラメーター", - "bc_gi_api":"ブロックチェーンへの接続の開始", - "bc_gi_param":"(なし)", - "bc_ge_api":"ブロックチェーンイベントの登録", - "bc_ge_param":"(なし)", - "bc_gh_api":"歴史家の取得", - "bc_gh_param":"(なし)" - }, - "buyer": { - "title":"購入者弟06章. 購入者を選択してビューの表示: ", - "newOrder":"新規発注の作成", - "orderStatus":"発注状況の表示" - }, - "createConnectionProfile": { - "title":"ここに新しいプロファイルの名前を入力してください: ", - "cp_type":"タイプ", - "cp_orderers":"発注者", - "cp_orderers_url":"url", - "cp_ca":"ca", - "cp_ca_url":"url", - "cp_ca_name":"名", - "cp_peers":"同僚", - "cp_peers_event_url":"イベントURL", - "cp_peers_request_url":"依頼URL", - "cp_keyValStore":"keyValStore", - "cp_channel":"チャネル", - "cp_mspID":"mspID", - "cp_timeout":"タイムアウト", - "cancel":"キャンセル", - "submit":"提出" - }, - "createMember": { - "cd_type":"タイプ", - "cd_buyer":"購入者", - "cd_seller":"販売者", - "cd_shipper":"荷送人", - "cd_provider":"プロバイダ", - "cd_financeco":"財務会社", - "cd_cn":"会社名", - "cd_e":"e-メールアドレス", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "createOrder": { - "title":"新規発注の作成", - "selectVendor":"ベンダーの選択: ", - "cn_on":"発注番号", - "cn_status":"状態", - "cn_date":"日付", - "cn_total":"合計", - "cn_selectItem":"アイテムの選択", - "addItem":"アイテムの追加", - "cancelNewOrder":"キャンセル", - "submitNewOrder":"提出" - }, - "deleteConnectionProfile": { - "title":"削除するプロファイルの選択: ", - "cancel":"キャンセル", - "submit":"提出" - }, - "financeCo": { - "title":"Zero To Blockchain弟12章: グローバル・ファイナンシャー", - "financeCOclear":"ウィンドウのクリア", - "financeCOorderStatus":"発注状況の表示" - }, - "getMemberSecret": { - "gs_type":"タイプ", - "gs_members":"メンバー", - "gs_company":"会社名", - "gs_email":"e-メールアドレス", - "gs_userID":"ユーザーID", - "gs_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "provider": { - "title":"プロバイダ弟12章, プロバイダを選択してビューの表示: ", - "provider_clear":"ウィンドウのクリア", - "providerOrderStatus":"発注状況の表示" - }, - "removeMember": { - "rm_type":"タイプ", - "rm_members":"メンバー", - "rm_company":"会社名", - "rm_email":"e-メールアドレス", - "rm_userID":"ユーザーID", - "rm_secret":"シークレット", - "cancel":"キャンセル", - "submit":"提出" - }, - "seller": { - "title":"販売者弟12章, 販売者を選択してビューの表示: ", - "seller_clear":"ウィンドウのクリア", - "sellerOrderStatus":"発注状況の表示" - }, - "shipper": { - "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", - "shipper_clear":"ウィンドウのクリア", - "shipperOrderStatus":"発注状況の表示 " - }, - "singleUX": {}, - "orderProcess": { - "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, - "Dispute": {"select": "紛争","message":"紛争"}, - "Resolve": {"select": "解決","message":"解決"}, - "Purchase": {"select": "購入","message":"購入"}, - "Cancel": {"select": "キャンセル","message":"キャンセル"}, - "Pay": {"select": "支払い","message":"支払い"}, - "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, - "BackOrder": {"select": "バックワード","message":"バックワード"}, - "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, - "Refund": {"select": "払い戻し","message":"払い戻し"}, - "Delivered": {"select": "配信されました","message":"配信されました"}, - "Delivering": {"select": "配信されています","message":"配信状況の更新"}, - "Order": {"select": "発注","message":"サプライヤからの発注"}, - "NoAction": {"select": "アクションがありません","message":"何もしない"}, - "ex_button":"実行", - "ca_button":"キャンセル", - "orderno":"発注 #", - "status":"状態", - "total":"合計", - "seller":"販売者: ", - "itemno":"アイテム番号", - "description":"説明", - "qty":"数量", - "price":"価格", - "processing_msg":"発注番号の処理{0}依頼:{1}", - "b_no_order_msg":"本購入者の発注はありません: ", - "s_no_order_msg":"本販売者の発注はありません: ", - "p_no_order_msg":"本プロバイダの発注はありません: ", - "sh_no_order_msg":"本荷送人の発注はありません: ", - "create_msg":"発注の作成の処理", - "buyer":"購入者: " - }, - "financeCoOrder": { - "status":"現在の状態: ", - "action":"アクション", - "by":"から", - "date":"日付", - "comments":"コメント", - "created":"作成されました", - "cancelled":"キャンセルされましたか?", - "notCancel":"(キャンセルされていません)", - "purchased":"購入されました", - "noPurchase":"(購入依頼がありません)", - "thirdParty":"第三者発注", - "nothirdParty":"(まだ第三者に送られていません)", - "backordered":"バックワードされていますか?", - "notBackordered":"(バックワードされていません)", - "shippingRequested":"出荷の依頼", - "noRequestShip":"(荷送人への依頼がありません)", - "shippingStarted":"出荷の開始", - "noDeliveryStart":"(出荷は開始されていません)", - "delivered":"配信されました", - "notDelivered":"(配信されていません)", - "payRequested":"支払いの依頼", - "noRequest":"(支払いの依頼がありません)", - "disputed":"紛争は申請されました", - "noDispute":"(紛争ではありません)" - } - } \ No newline at end of file + "index": {"language":"米国英語", + "title":"Z2B 弟 12章", + "header":"弟 12章: イベントの操作", + "titleBar":"Zero to Blockchainチュートリアル", + "idx_unified":"統合ユーザー経験のロード", + "idx_buyer":"購入者ユーザー経験のロード", + "idx_seller":"販売者ユーザー経験のロード", + "idx_provider":"プロバイダユーユーザー経験のロード", + "idx_shipper":"荷送人ユーザー経験のロード", + "idx_financeco":"財務会社ユーザー経験のロード", + "idx_roles":"役割", + "idx_admin":"管理者", + "idx_adminUX":"管理者ユーザー経験のロード", + "idx_preload":"事前ロードネットワーク" + }, + "admin": { + "title":"Zero To Blockchain 弟05章", + "npm":"ネットワークプロファイル管理", + "npm_API":"API", + "npm_param":"パラメーター", + "npm_dp_api":"プロフィールの削除", + "npm_dp_param":"プロフィール名", + "npm_cp_api":"プロフィールの作成", + "npm_cp_param":"プロファイルオブジェクト", + "npm_ga_api":"すべての接続プロファイルの取得", + "npm_ga_param":"(なし)", + "npm_g1_api":"特定のネットワーク接続プロファイルの取得", + "npm_g1_param":"プロフィール名", + "bnm":"ビジネスネットワーク管理", + "bnm_param":"パラメーター", + "bnm_api":"API", + "bnm_nd_api":"ネットワークの展開", + "bnm_nd_param":"ネットワークアーカイブファイル、オプション", + "bnm_ni_api":"新規ネットワークのインストールする", + "bnm_ni_param":"ネットワークアーカイブファイル、オプション", + "bnm_ns_api":"インストールされたネットワークの開始", + "bnm_ns_param":"ネットワーク名、オプション", + "bnm_nl_api":"展開されたビジネスネットワークの一覧表示", + "bnm_nl_param":"(なし)", + "bnm_np_api":"ネットワークに触れる、互換性をチェックする", + "bnm_np_param":"ビジネスネットワーク名", + "bnm_nu_api":"ビジネスネットワークをオフラインにする", + "bnm_nu_param":"ビジネスネットワーク名<", + "bnm_nuu_api":"既存のビジネスネットワークの更新", + "bnm_nuu_param":"ビジネスネットワーク名、アーカイブファイル", + "rm":"リソース管理", + "rm_api":"API", + "rm_param":"パラメーター", + "rm_lr_api":"レジストリのメンバーの一覧表示", + "rm_la_api":"レジストリのリストアセット", + "rm_la_param":"(なし)", + "rm_am_api":"メンバーの追加", + "rm_am_param":"Co 名, id, タイプ", + "rm_rm_api":"メンバーの削除", + "rm_gs_api":"メンバーシークレットの取得", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Check if card exists", + "rm_cc2_api": "Create Card", + "bc":"ブロックチェーン", + "bc_api":"API", + "bc_param":"パラメーター", + "bc_gi_api":"ブロックチェーンへの接続の開始", + "bc_gi_param":"(なし)", + "bc_ge_api":"ブロックチェーンイベントの登録", + "bc_ge_param":"(なし)", + "bc_gh_api":"歴史家の取得", + "bc_gh_param":"(なし)" + }, + "buyer": { + "title":"購入者弟06章. 購入者を選択してビューの表示: ", + "newOrder":"新規発注の作成", + "orderStatus":"発注状況の表示" + }, + "createConnectionProfile": { + "title":"ここに新しいプロファイルの名前を入力してください: ", + "cp_type":"タイプ", + "cp_orderers":"発注者", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"名", + "cp_peers":"同僚", + "cp_peers_event_url":"イベントURL", + "cp_peers_request_url":"依頼URL", + "cp_keyValStore":"keyValStore", + "cp_channel":"チャネル", + "cp_mspID":"mspID", + "cp_timeout":"タイムアウト", + "cancel":"キャンセル", + "submit":"提出" + }, + "createMember": { + "cd_type":"タイプ", + "cd_buyer":"購入者", + "cd_seller":"販売者", + "cd_shipper":"荷送人", + "cd_provider":"プロバイダ", + "cd_financeco":"財務会社", + "cd_cn":"会社名", + "cd_e":"e-メールアドレス", + "cancel":"キャンセル", + "submit":"提出" + }, + "createOrder": { + "title":"新規発注の作成", + "selectVendor":"ベンダーの選択: ", + "cn_on":"発注番号", + "cn_status":"状態", + "cn_date":"日付", + "cn_total":"合計", + "cn_selectItem":"アイテムの選択", + "addItem":"アイテムの追加", + "cancelNewOrder":"キャンセル", + "submitNewOrder":"提出" + }, + "deleteConnectionProfile": { + "title":"削除するプロファイルの選択: ", + "cancel":"キャンセル", + "submit":"提出" + }, + "financeCo": { + "title":"Zero To Blockchain弟10章: グローバル・ファイナンシャー", + "financeCOclear":"ウィンドウのクリア", + "financeCOorderStatus":"発注状況の表示" + }, + "getMemberSecret": { + "gs_type":"タイプ", + "gs_members":"メンバー", + "gs_company":"会社名", + "gs_email":"e-メールアドレス", + "gs_userID":"ユーザーID", + "gs_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "provider": { + "title":"プロバイダ弟08章, プロバイダを選択してビューの表示: ", + "provider_clear":"ウィンドウのクリア", + "providerOrderStatus":"発注状況の表示" + }, + "removeMember": { + "rm_type":"タイプ", + "rm_members":"メンバー", + "rm_company":"会社名", + "rm_email":"e-メールアドレス", + "rm_userID":"ユーザーID", + "rm_secret":"シークレット", + "cancel":"キャンセル", + "submit":"提出" + }, + "seller": { + "title":"販売者弟07章, 販売者を選択してビューの表示: ", + "seller_clear":"ウィンドウのクリア", + "sellerOrderStatus":"発注状況の表示" + }, + "shipper": { + "title":"荷送人弟09章, 荷送人を選択してビューの表示: ", + "shipper_clear":"ウィンドウのクリア", + "shipperOrderStatus":"発注状況の表示 " + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "支払いの承認","message":"支払いの承認"}, + "Dispute": {"select": "紛争","message":"紛争"}, + "Resolve": {"select": "解決","message":"解決"}, + "Purchase": {"select": "購入","message":"購入"}, + "Cancel": {"select": "キャンセル","message":"キャンセル"}, + "Pay": {"select": "支払い","message":"支払い"}, + "RequestShipping": {"select": "出荷の依頼","message":"出荷の依頼"}, + "BackOrder": {"select": "バックワード","message":"バックワード"}, + "PayRequest": {"select": "支払いの依頼","message":"支払いの依頼"}, + "Refund": {"select": "払い戻し","message":"払い戻し"}, + "Delivered": {"select": "配信されました","message":"配信されました"}, + "Delivering": {"select": "配信されています","message":"配信状況の更新"}, + "Order": {"select": "発注","message":"サプライヤからの発注"}, + "NoAction": {"select": "アクションがありません","message":"何もしない"}, + "ex_button":"実行", + "ca_button":"キャンセル", + "orderno":"発注 #", + "status":"状態", + "total":"合計", + "seller":"販売者: ", + "itemno":"アイテム番号", + "description":"説明", + "qty":"数量", + "price":"価格", + "processing_msg":"発注番号の処理{0}依頼:{1}", + "b_no_order_msg":"本購入者の発注はありません: ", + "s_no_order_msg":"本販売者の発注はありません: ", + "p_no_order_msg":"本プロバイダの発注はありません: ", + "sh_no_order_msg":"本荷送人の発注はありません: ", + "create_msg":"発注の作成の処理", + "buyer":"購入者: " + }, + "financeCoOrder": { + "status":"現在の状態: ", + "action":"アクション", + "by":"から", + "date":"日付", + "comments":"コメント", + "created":"作成されました", + "cancelled":"キャンセルされましたか?", + "notCancel":"(キャンセルされていません)", + "purchased":"購入されました", + "noPurchase":"(購入依頼がありません)", + "thirdParty":"第三者発注", + "nothirdParty":"(まだ第三者に送られていません)", + "backordered":"バックワードされていますか?", + "notBackordered":"(バックワードされていません)", + "shippingRequested":"出荷の依頼", + "noRequestShip":"(荷送人への依頼がありません)", + "shippingStarted":"出荷の開始", + "noDeliveryStart":"(出荷は開始されていません)", + "delivered":"配信されました", + "notDelivered":"(配信されていません)", + "payRequested":"支払いの依頼", + "noRequest":"(支払いの依頼がありません)", + "disputed":"紛争は申請されました", + "noDispute":"(紛争ではありません)" + } + } \ No newline at end of file diff --git a/Chapter12/controller/restapi/features/text/languages.json b/Chapter12/controller/restapi/features/text/languages.json index 7c65d9f..16398df 100644 --- a/Chapter12/controller/restapi/features/text/languages.json +++ b/Chapter12/controller/restapi/features/text/languages.json @@ -6,5 +6,5 @@ "French": {"active": "yes", "menu": "Le Français", "model": "fr-FR_BroadbandModel", "voice": "fr-FR_ReneeVoice", "data": "/text/fr/prompts.json"}, "Japanese": {"active": "yes", "menu": "Japanese", "model": "ja-JP_BroadbandModel", "voice": "ja-JP_EmiVoice", "data": "/text/jp/prompts.json"}, "Chinese": {"active": "yes", "menu": "Chinese", "model": "zh-CN_BroadbandModel", "voice": "", "data": "/text/ch/prompts.json"}, -"Brazilian_Portuguese": {"active": "no", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} +"Brazilian_Portuguese": {"active": "yes", "menu": "Português do Brasi", "model": "pt-BR_BroadbandModel", "voice": "pt-BR_IsabelaVoice", "data": "/text/pt/prompts.json"} } diff --git a/Chapter12/controller/restapi/features/text/pt/prompts.json b/Chapter12/controller/restapi/features/text/pt/prompts.json index 4a3c1db..4b6d919 100644 --- a/Chapter12/controller/restapi/features/text/pt/prompts.json +++ b/Chapter12/controller/restapi/features/text/pt/prompts.json @@ -1,7 +1,222 @@ { - "index": {"language": "Português do Brasi", - "title": "Saiba Bluemix agora!", - "header": "Capítulo 3: (Versão Português) criando o seu primeiro deputado Watson app", - "titleBar": "Zero de déficit cognitivo Tutorial", - "speech": "Falei a saída vai aqui"} -} + "index": {"language":"Inglês Americano", + "title":"Z2B Capítulo 12", + "header":"Capítulo 12: Trabalhando com Eventos", + "titleBar":"Tutorial Zero to Blockchain", + "idx_unified":"carregar a Experiência de Usuário Unificado", + "idx_buyer":"carregar a Experiência de Usuário Consumidor", + "idx_seller":"carregar a Experiência de Usuário Vendedor", + "idx_provider":"carregar a Experiência de Usuário Fornecedor", + "idx_shipper":"carregar a Experiência de Usuário Transportador", + "idx_financeco":"carregar a Experiência de Usuário da Empresa Financeira", + "idx_roles":"Cargos", + "idx_admin":"Administrador ", + "idx_adminUX":"carregar a Experiência de Usuário Administrador", + "idx_preload":"Carregar previamente a rede" + }, + "admin": { + "title":"Zero to Blockchain Capítulo 5", + "npm":"Gerenciamento de perfil de rede", + "npm_API":"API", + "npm_param":"Parametros", + "npm_dp_api":"deletar perfil", + "npm_dp_param":"nome do perfil", + "npm_cp_api":"criar perfil", + "npm_cp_param":"objeto de perfil", + "npm_ga_api":"obter todos os perfis de conexão", + "npm_ga_param":"", + "npm_g1_api":"obter um perfil específico de conexão de rede", + "npm_g1_param":"nome do perfil", + "bnm":"Gerenciamento da rede de negócios", + "bnm_param":"Parametros", + "bnm_api":"API", + "bnm_nd_api":"implantar uma rede", + "bnm_nd_param":"arquivar arquivo de rede, opções", + "bnm_ni_api":"instalar nova rede", + "bnm_ni_param":"arquivar arquivo de rede, opções", + "bnm_ns_api":"Iniciar rede instalada", + "bnm_ns_param":"nome da rede, opções", + "bnm_nl_api":"listas de redes de negócios implantadas", + "bnm_nl_param":"", + "bnm_np_api":"toque uma rede, verifique a compatibilidade", + "bnm_np_param":"nome da rede de negócios", + "bnm_nu_api":"pegue uma rede de negócios off line", + "bnm_nu_param":"nome da rede de negócios", + "bnm_nuu_api":"atualizar rede de negócios existente", + "bnm_nuu_param":"nome da rede de negócios, arquivar arquivo", + "rm":"Gestão de Recursos", + "rm_api":"API", + "rm_param":"Parametros", + "rm_lr_api":"lista membros de um registro", + "rm_la_api":"Lista de ativos no registro", + "rm_la_param":"", + "rm_am_api":"Adicionar Membro", + "rm_am_param":"Co Nome, id, Tipo", + "rm_rm_api":"Remover Membro", + "rm_gs_api":"getMemberSecret", + "rm_ii_api":"Issue Identity", + "rm_cc_api":"Verifique se o cartão de identidade existe", + "rm_cc2_api": "criar um documento de identidade", + "bc":"BlockChain", + "bc_api":"API", + "bc_param":"Parametros", + "bc_gi_api":"iniciar conexão com Blockchain", + "bc_gi_param":"", + "bc_ge_api":"Registro para eventos de Blockchain", + "bc_ge_param":"", + "bc_gh_api":"obter histórico", + "bc_gh_param":"" + }, + "buyer": { + "title":"Capítulo do Consumidor 06. Selecione Consumidor para ver sua visão:", + "newOrder":"Criar novo pedido", + "orderStatus":"Exibir Estatus de Pedidos" + }, + "createConnectionProfile": { + "title":"Digite o nome de perfil novo aqui:", + "cp_type":"tipo", + "cp_orderers":"ordenadores", + "cp_orderers_url":"url", + "cp_ca":"ca", + "cp_ca_url":"url", + "cp_ca_name":"nome", + "cp_peers":"colegas", + "cp_peers_event_url":"eventURL", + "cp_peers_request_url":"requestURL", + "cp_keyValStore":"keyValStore", + "cp_channel":"canal", + "cp_mspID":"mspID", + "cp_timeout":"Tempo Esgotado", + "cancel":"cancelar", + "submit":"submeter" + }, + "createMember": { + "cd_type":"Tipo", + "cd_buyer":"Consumidor", + "cd_seller":"Vendedor", + "cd_shipper":"Transportador", + "cd_provider":"Fornecedor", + "cd_financeco":"Empresa Financeira", + "cd_cn":"Nome da Empresa", + "cd_e":"Endereço de email", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "createOrder": { + "title":"Criar novo pedido", + "selectVendor":"Selecione Vendedor:", + "cn_on":"Numero do Pedido", + "cn_status":"Estatus", + "cn_date":"Data", + "cn_total":"Total", + "cn_selectItem":"Selecionar Item", + "addItem":"Adicionar Item", + "cancelNewOrder":"cancelar", + "submitNewOrder":"submeter" + }, + "deleteConnectionProfile": { + "title":"Selecionar Perfil para deletar:", + "cancel":"cancelar", + "submit":"submeter" + }, + "financeCo": { + "title":"Zero to Blockchain Capítulo 10: O Financeiro Global", + "financeCOclear":"Limpar Janela", + "financeCOorderStatus":"Exibir Estatus de Pedidos" + }, + "getMemberSecret": { + "gs_type":"Tipo", + "gs_members":"Membros", + "gs_company":"Nome da Empresa", + "gs_email":"Endereço de email", + "gs_userID":"userID", + "gs_secret":"secret", + "cancel":"cancelar", + "submit":"submeter" + }, + "provider": { + "title":"Capítulo do Fornecedor 08. Selecione Fornecedor para ver sua visão:", + "provider_clear":"Limpar Janela", + "providerOrderStatus":"Exibir Estatus de Pedidos" + }, + "removeMember": { + "rm_type":"Tipo", + "rm_members":"Membros", + "rm_company":"Nome da Empresa", + "rm_email":"Endereço de email", + "rm_userID":"userID", + "rm_secret":"secret", + "cancel":"Cancelar", + "submit":"Submeter" + }, + "seller": { + "title":"Capítulo do Vendedor 07. Selecione Vendedor para ver sua visão:", + "seller_clear":"Limpar Janela", + "sellerOrderStatus":"Exibir Estatus de Pedidos" + }, + "shipper": { + "title":"Capítulo do Transportador 09. Selecione Transportador para ver sua visão:", + "shipper_clear":"Limpar Janela", + "shipperOrderStatus":"Exibir Estatus de Pedidos" + }, + "singleUX": {}, + "orderProcess": { + "AuthorizePayment": {"select": "Autorizar Pagamento","message":"Autorizar Pagamento"}, + "Dispute": {"select": "Disputa","message":"Disputa"}, + "Resolve": {"select": "Resolver","message":"Resolver"}, + "Purchase": {"select": "Compra","message":"Compra"}, + "Cancel": {"select": "Cancelar","message":"Cancelar"}, + "Pay": {"select": "Pagar","message":"Pagar"}, + "RequestShipping": {"select": "Solicitar Envio","message":"Solicitar Envio"}, + "BackOrder": {"select": "Reencaminhar","message":"Reencaminhar"}, + "PayRequest": {"select": "Pedido de pagamento","message":"Pedido de pagamento"}, + "Refund": {"select": "Reembolsar","message":"Reembolsar"}, + "Delivered": {"select": "Entregue","message":"Entregue"}, + "Delivering": {"select": "Entregando","message":"Atualizar Estatus de Pedido"}, + "Order": {"select": "Pedido","message":"Pedido do fornecedor"}, + "NoAction": {"select": "Sem Ação","message":"Não tome nenhuma ação"}, + "ex_button":"Executar", + "ca_button":"Cancelar", + "orderno":"Pedido #", + "status":"Estatus", + "total":"Total", + "seller":"Vendedor:", + "itemno":"Numero do Item", + "description":"Descrição", + "qty":"Quantidade", + "price":"Preço", + "processing_msg":"Processando {0} solicitação para o número do pedido: {1}", + "b_no_order_msg":"Sem pedidos para esse consumidor:", + "s_no_order_msg":"Sem pedidos para esse vendedor:", + "p_no_order_msg":"Sem pedidos para esse fornecedor:", + "sh_no_order_msg":"Sem pedidos para esse transportador:", + "create_msg":"Processando requerimento de criar pedido", + "buyer":"Consumidor:" + }, + "financeCoOrder": { + "status":"Estatus Atual", + "action":"Ação", + "by":"Por", + "date":"Data", + "comments":"Comentarios", + "created":"Criado", + "cancelled":"Cancelado", + "notCancel":"(não cancelado)", + "purchased":"Comprado", + "noPurchase":"(sem solicitação de compra)", + "thirdParty":"Pedido de terceiros", + "nothirdParty":"(ainda não enviado para terceiros)", + "backordered":"Reencaminhado?", + "notBackordered":"(não reencaminhado)", + "shippingRequested":"Envio Solicitado", + "noRequestShip":"(sem solicitação de envio)", + "shippingStarted":"Envio Iniciado", + "noDeliveryStart":"Entrega não iniciada", + "delivered":"Entregue", + "notDelivered":"(ainda não entregue)", + "payRequested":"Pagamento solicitado", + "noRequest":"(sem solicitação de pagamento)", + "disputed":"Disputa levantada", + "noDispute":"(não em disputa)" + } + } \ No newline at end of file diff --git a/Chapter12/controller/restapi/router.js b/Chapter12/controller/restapi/router.js index c8171fc..ba7b3cc 100644 --- a/Chapter12/controller/restapi/router.js +++ b/Chapter12/controller/restapi/router.js @@ -12,27 +12,56 @@ * limitations under the License. */ +'use strict'; -var express = require('express'); -var router = express.Router(); -var format = require('date-format'); +let express = require('express'); +let router = express.Router(); +let format = require('date-format'); -var multi_lingual = require('./features/multi_lingual'); -var resources = require('./features/resources'); -var getCreds = require('./features/getCredentials'); -var hlcAdmin = require('./features/composer/hlcAdmin'); -var hlcClient = require('./features/composer/hlcClient'); -var hlcFabric = require('./features/composer/queryBlockChain'); -var setup = require('./features/composer/autoLoad'); +let multi_lingual = require('./features/multi_lingual'); +let resources = require('./features/resources'); +let getCreds = require('./features/getCredentials'); +let hlcAdmin = require('./features/composer/hlcAdmin'); +let hlcClient = require('./features/composer/hlcClient'); +let setup = require('./features/composer/autoLoad'); +let hlcFabric = require('./features/composer/queryBlockChain'); + + +router.get('/fabric/getChainInfo', hlcFabric.getChainInfo); +router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); +router.get('/fabric/getHistory', hlcAdmin.getHistory); + +router.post('/setup/autoLoad*', setup.autoLoad); +router.get('/setup/getPort*', setup.getPort); +router.get('/composer/client/initEventRegistry*', hlcClient.init_z2bEvents); + +router.get('/setup/getAlertPort*', setup.getAlertPort); +router.get('/setup/getFinanceAlertPort*', setup.getFinanceAlertPort); module.exports = router; -var count = 0; +let count = 0; +/** + * This is a request tracking function which logs to the terminal window each request coming in to the web serve and + * increments a counter to allow the requests to be sequenced. + * @param {express.req} req - the inbound request object from the client + * @param {express.res} res - the outbound response object for communicating back to client + * @param {express.next} next - an express service to enable post processing prior to responding to the client + * + * @function + */ router.use(function(req, res, next) { - count++; - console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); - next(); // make sure we go to the next routes and don't stop here + count++; + console.log('['+count+'] at: '+format.asString('hh:mm:ss.SSS', new Date())+' Url is: ' + req.url); + next(); // make sure we go to the next routes and don't stop here }); +// the following get and post statements tell nodeJS what to do when a request comes in +// The request is the single quoted phrase following the get( or post( statement. +// the text at the end identifies which function in which require(d) module to implement +// These are searched in order by get/post request. +// The asterisk (*) means 'ignore anything following this point' +// which means we have to be careful about ordering these statements. +// router.get('/api/getSupportedLanguages*',multi_lingual.languages); router.get('/api/getTextLocations*',multi_lingual.locations); router.post('/api/selectedPrompts*',multi_lingual.prompts); @@ -47,7 +76,6 @@ router.get('/composer/admin/getCreds*', hlcAdmin.getCreds); router.get('/composer/admin/getAllProfiles*', hlcAdmin.getAllProfiles); router.get('/composer/admin/listAsAdmin*', hlcAdmin.listAsAdmin); router.get('/composer/admin/getRegistries*', hlcAdmin.getRegistries); -router.get('/composer/admin/listAsPeerAdmin*', hlcAdmin.listAsPeerAdmin); router.post('/composer/admin/createProfile*', hlcAdmin.createProfile); router.post('/composer/admin/deleteProfile*', hlcAdmin.deleteProfile); @@ -64,20 +92,12 @@ router.post('/composer/admin/getAssets*', hlcAdmin.getAssets); router.post('/composer/admin/addMember*', hlcAdmin.addMember); router.post('/composer/admin/removeMember*', hlcAdmin.removeMember); router.post('/composer/admin/getSecret*', setup.getMemberSecret); +router.post('/composer/admin/checkCard*', hlcAdmin.checkCard); +router.post('/composer/admin/createCard*', hlcAdmin.createCard); +router.post('/composer/admin/issueIdentity*', hlcAdmin.issueIdentity); -router.post('/setup/autoLoad*', setup.autoLoad); -router.get('/setup/getPort*', setup.getPort); -router.get('/setup/getAlertPort*', setup.getAlertPort); -router.get('/setup/getFinanceAlertPort*', setup.getFinanceAlertPort); - +// router requests specific to the Buyer router.get('/composer/client/getItemTable*', hlcClient.getItemTable); router.post('/composer/client/getMyOrders*', hlcClient.getMyOrders); router.post('/composer/client/addOrder*', hlcClient.addOrder); -router.post('/composer/client/orderAction*', hlcClient.orderAction); - -router.get('/fabric/getChainInfo', hlcFabric.getChainInfo); -router.get('/fabric/getChainEvents', hlcFabric.getChainEvents); -router.get('/fabric/getHistory', hlcAdmin.getHistory); - -router.get('/composer/client/initEventRegistry*', hlcClient.init_z2bEvents); - +router.post('/composer/client/orderAction*', hlcClient.orderAction); \ No newline at end of file diff --git a/Chapter12/createArchive.sh b/Chapter12/createArchive.sh index f7640c6..cb2371a 100755 --- a/Chapter12/createArchive.sh +++ b/Chapter12/createArchive.sh @@ -77,4 +77,8 @@ echo -e "Network Name is: ${GREEN} $NETWORK_NAME ${RESET}" | indent showStep "creating archive" cd ./network -composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna \ No newline at end of file +composer archive create --sourceType dir --sourceName . -a ./dist/$NETWORK_NAME.bna +# +# new create command from tutorial is following: +# composer archive create -t dir -n . +# \ No newline at end of file diff --git a/Chapter12/deployNetwork.sh b/Chapter12/deployNetwork.sh index 9c13a36..d9042c9 100755 --- a/Chapter12/deployNetwork.sh +++ b/Chapter12/deployNetwork.sh @@ -80,12 +80,38 @@ showStep "deploying network" # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -i PeerAdmin -s randomString # -# what the documentation implies is required +# what the v0.14 documentation implies is required # cd network/dist # composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString # -# what really works -composer identity request -p hlfv1 -i admin -s adminpw -composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# what really works for v0.14 +# composer identity request -p hlfv1 -i admin -s adminpw +# composer identity import -p hlfv1 -u admin -c ~/.identityCredentials/admin-pub.pem -k ~/.identityCredentials/admin-priv.pem +# cd network/dist +# composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +# +# documentation for v0.15 +# cd network/dist -composer network deploy -a $NETWORK_NAME.bna -p hlfv1 -A admin -S adminpw -i PeerAdmin -s randomString +showStep "installing PeerAdmin card" +composer runtime install --card PeerAdmin@hlfv1 --businessNetworkName $NETWORK_NAME +showStep "starting network" +# change in documentation +# composer network start --card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --archiveFile $NETWORK_NAME.bna --file networkadmin.card +# corrected to: +composer network start -c PeerAdmin@hlfv1 -A admin -S adminpw -a $NETWORK_NAME.bna --file networkadmin.card +showStep "importing networkadmin card" +if composer card list -n admin@$NETWORK_NAME > /dev/null; then + composer card delete -n admin@$NETWORK_NAME +fi +composer card import --file networkadmin.card +showStep "pinging admin@$NETWORK_NAME card" +composer network ping --card admin@$NETWORK_NAME +# +# creating card for test program +# composer card create -p controller/restapi/features/composer/creds/connection.json -u defaultProfile -c controller/restapi/features/composer/creds/admin@org.hyperledger.composer.system-cert.pem -k controller/restapi/features/composer/creds/114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin +# composer card import --file defaultProfile@hlfv1.card +# showStep "pinging defaultProfile@hlfv1 card" +# composer network ping --card defaultProfile@hlfv1 +# + diff --git a/Chapter12/favicon.ico b/Chapter12/favicon.ico index 4126853..fc9e25d 100755 Binary files a/Chapter12/favicon.ico and b/Chapter12/favicon.ico differ diff --git a/Chapter12/network/dist/networkadmin.card b/Chapter12/network/dist/networkadmin.card new file mode 100644 index 0000000..3e6d6b9 Binary files /dev/null and b/Chapter12/network/dist/networkadmin.card differ diff --git a/Chapter12/network/lib/sample.js b/Chapter12/network/lib/sample.js index 13f7a74..c9ff3b3 100644 --- a/Chapter12/network/lib/sample.js +++ b/Chapter12/network/lib/sample.js @@ -347,21 +347,10 @@ function displayObjectValues (_string, _object) function z2bEmit(_event, _order) { var method = 'z2bEmit'; - // get the factory - /* - * YOUR CODE HERE - * - */ - // create a new event - /* - * YOUR CODE HERE - * - */ - // update the event with the order ID and the buyerID - /* - * YOUR CODE HERE - * - */ + var factory = getFactory(); + var z2bEvent = factory.newEvent(ns, _event); + z2bEvent.orderID = _order.$identifier; + z2bEvent.buyerID = _order.buyer.$identifier; switch (_event) { case 'Created': @@ -369,53 +358,38 @@ function z2bEmit(_event, _order) break; case 'Bought': case 'PaymentRequested': - // these events have the same members - /* - * YOUR CODE HERE - * - */ + z2bEvent.sellerID = _order.seller.$identifier; + z2bEvent.financeCoID = _order.financeCo.$identifier; break; case 'Ordered': case 'Cancelled': case 'Backordered': - /* - * YOUR CODE HERE - * - */ + z2bEvent.sellerID = _order.seller.$identifier; + z2bEvent.providerID = _order.provider.$identifier; break; case 'ShipRequest': case 'DeliveryStarted': case 'DeliveryCompleted': - // these events have the same members - /* - * YOUR CODE HERE - * - */ + z2bEvent.sellerID = _order.seller.$identifier; + z2bEvent.providerID = _order.provider.$identifier; + z2bEvent.shipperID = _order.shipper.$identifier; break; case 'DisputeOpened': case 'Resolved': case 'Refunded': case 'Paid': - // these events have the same members - /* - * YOUR CODE HERE - * - */ + z2bEvent.sellerID = _order.seller.$identifier; + z2bEvent.providerID = _order.provider.$identifier; + z2bEvent.shipperID = _order.shipper.$identifier; + z2bEvent.financeCoID = _order.financeCo.$identifier; break; case 'PaymentAuthorized': - // these events have the same members - /* - * YOUR CODE HERE - * - */ + z2bEvent.sellerID = _order.seller.$identifier; + z2bEvent.financeCoID = _order.financeCo.$identifier; break; default: break; } - // emit the populated event - /* - * YOUR CODE HERE - * - */ + emit(z2bEvent); return } \ No newline at end of file diff --git a/Chapter12/network/models/sample.cto b/Chapter12/network/models/sample.cto index 7cc93d2..2bd8d5f 100644 --- a/Chapter12/network/models/sample.cto +++ b/Chapter12/network/models/sample.cto @@ -142,104 +142,102 @@ event Created extends Z2BEvent { } // notification that an order has been placed event Bought extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String financeCoID } // notification that a fulfillment request has been placed event Ordered extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID } // notification that an order has been cancelled event Cancelled extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID } // notification that items are on backorder event Backordered extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID } // notification that shipper has been contacted event ShipRequest extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID + o String shipperID } // notification that order in being delivered event DeliveryStarted extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID + o String shipperID } // notification that order has been delivered event DeliveryCompleted extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID + o String shipperID } // notification that order is in dispute event DisputeOpened extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID + o String shipperID + o String financeCoID } // notification that dispute has been resolved event Resolved extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID + o String shipperID + o String financeCoID } // notification that an order has been refunded event Refunded extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID + o String shipperID + o String financeCoID } // notification that a request for payment has been issued event PaymentRequested extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String financeCoID } // notification that a request for payment has been approved by the buyer event PaymentAuthorized extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String financeCoID } // notification that order has been paid / event Paid extends Z2BEvent { - /* - * YOUR CODE HERE - * - */ + o String sellerID + o String buyerID + o String providerID + o String shipperID + o String financeCoID } \ No newline at end of file diff --git a/Chapter12/network/package.json b/Chapter12/network/package.json index be89bc0..5ef56b0 100644 --- a/Chapter12/network/package.json +++ b/Chapter12/network/package.json @@ -36,11 +36,11 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-admin": "^0.14.0", - "composer-cli": "^0.14.0", - "composer-client": "^0.14.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", + "composer-admin": "^0.16.0", + "composer-cli": "^0.16.0", + "composer-client": "^0.16.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", diff --git a/Chapter12/network/test/sample.js b/Chapter12/network/test/sample.js index 1c3e3e6..4bacd5f 100644 --- a/Chapter12/network/test/sample.js +++ b/Chapter12/network/test/sample.js @@ -14,18 +14,11 @@ 'use strict'; -const AdminConnection = require('composer-admin').AdminConnection; -const BrowserFS = require('browserfs/dist/node/index'); const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection; -const BusinessNetworkDefinition = require('composer-common').BusinessNetworkDefinition; -const path = require('path'); require('chai').should(); -const network = 'zerotoblockchain-network'; -const adminID = 'admin'; -const adminPW = 'adminpw'; -const bfs_fs = BrowserFS.BFSRequire('fs'); +const _timeout = 90000; const NS = 'org.acme.Z2BTestNetwork'; const orderNo = '12345'; const buyerID = 'billybob@email.com'; @@ -110,30 +103,12 @@ function addItems (_inbound) return (_inbound); } -describe('Finance Network', () => { - - // let adminConnection; +describe('Finance Network', function () { + this.timeout(_timeout); let businessNetworkConnection; - - before(() => { - BrowserFS.initialize(new BrowserFS.FileSystem.InMemory()); - const adminConnection = new AdminConnection({ fs: bfs_fs }); - return adminConnection.createProfile('defaultProfile', { - type: 'embedded' - }) - .then(() => { - return adminConnection.connect('defaultProfile', adminID, adminPW); - }) - .then(() => { - return BusinessNetworkDefinition.fromDirectory(path.resolve(__dirname, '..')); - }) - .then((businessNetworkDefinition) => { - return adminConnection.deploy(businessNetworkDefinition); - }) - .then(() => { - businessNetworkConnection = new BusinessNetworkConnection({ fs: bfs_fs }); - return businessNetworkConnection.connect('defaultProfile', network, adminID, adminPW); - }); + before(function () { + businessNetworkConnection = new BusinessNetworkConnection(); + return businessNetworkConnection.connect('admin@zerotoblockchain-network'); }); describe('#createOrder', () => { diff --git a/Chapter12/package.json b/Chapter12/package.json index 1d086ff..57535e3 100644 --- a/Chapter12/package.json +++ b/Chapter12/package.json @@ -17,7 +17,8 @@ "doc": "jsdoc --readme ./README.md --pedantic --recurse -c jsdoc.json -d network/out", "test-inner": "mocha -t 0 --recursive && cucumber-js", "test-cover": "nyc npm run test-inner", - "test": "mocha network/test --recursive -t 4000" + "test": "mocha network/test --recursive -t 4000", + "start": "node index" }, "repository": { "type": "git", @@ -37,13 +38,13 @@ "browserfs": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", - "composer-connector-embedded": "^0.14.0", - "composer-cucumber-steps": "^0.14.0", - "composer-admin": "^0.14.0", - "composer-client": "^0.14.0", - "composer-common": "^0.14.0", - "composer-runtime": "^0.14.0", - "composer-runtime-hlfv1": "^0.14.0", + "composer-connector-embedded": "^0.16.0", + "composer-cucumber-steps": "^0.16.0", + "composer-admin": "^0.16.0", + "composer-client": "^0.16.0", + "composer-common": "^0.16.0", + "composer-runtime": "^0.16.0", + "composer-runtime-hlfv1": "^0.16.0", "cucumber": "^2.2.0", "eslint": "^3.6.1", "istanbul": "^0.4.5", @@ -100,6 +101,7 @@ "http": "0.0.0", "https": "^1.0.0", "mime": "^2.0.2", + "os": "^0.1.1", "path": "^0.12.7", "sleep": "^5.1.1", "uuid": "^3.1.0", diff --git a/Chapter12/startup.sh b/Chapter12/startup.sh index 33108c7..a4602d8 100755 --- a/Chapter12/startup.sh +++ b/Chapter12/startup.sh @@ -1,11 +1,46 @@ #!/bin/bash -. ../common_OSX.sh + YELLOW='\033[1;33m' + RED='\033[1;31m' + GREEN='\033[1;32m' + RESET='\033[0m' + +# indent text on echo +function indent() { + c='s/^/ /' + case $(uname) in + Darwin) sed -l "$c";; + *) sed -u "$c";; + esac +} + +# Grab the current directory +function getCurrent() + { + showStep "getting current directory" + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + THIS_SCRIPT=`basename "$0"` + showStep "Running '${THIS_SCRIPT}'" + } + +# displays where we are, uses the indent function (above) to indent each line +function showStep () + { + echo -e "${YELLOW}=====================================================" | indent + echo -e "${RESET}-----> $*" | indent + echo -e "${YELLOW}=====================================================${RESET}" | indent + } showStep "using execs from previous installation, stored in ${HLF_INSTALL_PATH}" cd "${HLF_INSTALL_PATH}" showStep "starting fabric" -./startFabric.sh -showStep "creating new composer profile (required with each restart)" -./createComposerProfile.sh +~/fabric-tools/startFabric.sh +# +# no longer required with hyperledger composer V0.15 +# showStep "creating new composer profile (required with each restart)" +# ~/fabric-tools/createComposerProfile.sh +# +showStep "creating new PeerAdmin card (required with each restart)" +~/fabric-tools/createPeerAdminCard.sh +composer card list --name PeerAdmin@hlfv1 showStep "start up complete" \ No newline at end of file diff --git a/Chapter12/z2c_login b/Chapter12/z2c_login index 9743fc0..b8aba8a 100755 --- a/Chapter12/z2c_login +++ b/Chapter12/z2c_login @@ -1,6 +1,5 @@ #!/bin/bash -ded_URL="https://api.w3ibm.bluemix.net" pub_URL="https://api.ng.bluemix.net" gb_URL="https://api.eu-gb.bluemix.net" de_URL="https://api.eu-de.bluemix.net" @@ -18,7 +17,7 @@ then targetURL=$de_URL elif [[ $2 == "sydney" ]] then targetURL=$au_URL else - echo "Parameter 2 is required to be either 'dedicated' or one of the following public designations:" + echo "Parameter 2 is required to be one of the following public designations:" echo "North America: 'public', Great Britain: 'gb', Europe: 'germany', Australia: 'sydney'" echo "Please reissue the command as 'z2c_login {your_login_id} {dedicated || public || gb || germany || sydney}'" exit -1 diff --git a/setup_OSX.sh b/setup_OSX.sh index 79cbbdb..bc23155 100755 --- a/setup_OSX.sh +++ b/setup_OSX.sh @@ -56,20 +56,21 @@ function check4Brew () brew install dos2unix } -# check to see if nodev6 is installed. install it if it's not already there. +# check to see if nodev8 is installed. install it if it's not already there. function check4node () { if [[ $NODE_INSTALL == "true" ]]; then which node if [ "$?" -ne 0 ]; then - showStep "${RED}node not installed. installing Node V6" - brew install node@6 + showStep "${RED}node not installed. installing Node V8" + brew install node@8 else - if [[ `brew search /node@6/` != "node@6" ]]; then - showStep "${RED}found node $? installed, but not V6. installing Node V6" - brew install node@6 + if [[ `brew search /node@6/` != "node@8" ]]; then + showStep "${RED}found node $? installed, but not V8. installing Node V8" + brew install node@8 + echo "PATH=/usr/local/opt/node@8/bin:"'$PATH' >>~/.bash_profile else - showStep "${GREEN}Node V6 already installed" + showStep "${GREEN}Node V8 already installed" fi fi else @@ -77,6 +78,8 @@ function check4node () fi showStep "installing jsdoc globally" npm install -g jsdoc + showStep "installing node-gyp globally" + npm install -g node-gyp } # check to see if git is installed. install it if it's not already there. @@ -110,13 +113,14 @@ function installNodeDev () if [[ $SDK_INSTALL == "true" ]]; then showStep "The composer-cli contains all the command line operations for developing business networks." npm uninstall -g composer-cli - npm install -g composer-cli@0.14.2 + npm install -g composer-cli@0.16.0 showStep "The generator-hyperledger-composer is a Yeoman plugin that creates bespoke applications for your business network." npm uninstall -g generator-hyperledger-composer - npm install -g generator-hyperledger-composer@0.14.2 + npm install -g generator-hyperledger-composer@0.16.0 showStep "The composer-rest-server uses the Hyperledger Composer LoopBack Connector to connect to a business network, extract the models and then present a page containing the REST APIs that have been generated for the model." npm uninstall -g composer-rest-server - npm install -g composer-rest-server@0.14.2 + npm install -g composer-rest-server@0.16.0 + showStep "Yeoman is a tool for generating applications. When combined with the generator-hyperledger-composer component, it can interpret business networks and generate applications based on them." npm install -g yo else @@ -128,14 +132,34 @@ function installNodeDev () function install_hlf () { if [[ $HLF_INSTALL == "true" ]]; then - if [ ! -d "$HLF_INSTALL_PATH" ]; then - showStep "creating hlf tools folder $HLF_INSTALL_PATH " - mkdir -p "$HLF_INSTALL_PATH" + echo $HLF_INSTALL_PATH + if [ -d $HLF_INSTALL_PATH ]; then + showStep "removing $HLF_INSTALL_PATH" + rm -R "$HLF_INSTALL_PATH" + fi + if [ -d ~/.composer ]; then + showStep "removing .composer" + rm -R ~/.composer + fi + if [ -d ~/.composer-credentials ]; then + showStep "removing .composer-credentials" + rm -R ~/.composer-credentials fi + if [ -d ~/.composer-connection-profiles ]; then + showStep "removing .composer-connection-profiles" + rm -R ~/.composer-connection-profiles + fi + showStep "creating hlf tools folder $HLF_INSTALL_PATH " + mkdir -p "$HLF_INSTALL_PATH" cd "$HLF_INSTALL_PATH" pwd showStep "retrieving image scripts from git" - curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/v0.2.2/packages/fabric-dev-servers/fabric-dev-servers.zip + + curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.zip +# +# can no longer use V 0.2.2 with Composer v0.15 +# curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/v0.2.2/packages/fabric-dev-servers/fabric-dev-servers.zip +# showStep "unzipping images" unzip -o fabric-dev-servers.zip showStep "making scripts executable" @@ -147,15 +171,24 @@ function install_hlf () cd $HLF_INSTALL_PATH ./downloadFabric.sh showStep "installing platform specific binaries for OSX" - curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/v1.0.3/scripts/bootstrap-1.0.1.sh | bash +# +# v0.12-v0.14 +# curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/v1.0.4/scripts/bootstrap-1.0.1.sh | bash +# +# v0.15 +# curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap-1.0.1.sh | bash +# +# v 0.16 +# + curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/release/scripts/bootstrap-1.0.1.sh | bash export PATH=$HLF_INSTALL_PATH/bin:$PATH export HLF_INSTALL_PATH=$HLF_INSTALL_PATH showStep "updating .bash_profile with new paths" # ensure that the following lines start with a new line echo " " >>~/.bash_profile echo 'export FABRIC_VERSION=hlfv1' >>~/.bash_profile - echo "PATH=${HLF_INSTALL_PATH}/bin:/usr/local/opt/node@6/bin:"'$PATH' >>~/.bash_profile echo "export HLF_INSTALL_PATH=${HLF_INSTALL_PATH}" >>~/.bash_profile + echo "PATH=${HLF_INSTALL_PATH}/bin:"'$PATH' >>~/.bash_profile else showStep "${RED}skipping HyperLedger Fabric install" fi @@ -188,7 +221,7 @@ function printHeader () echo -e "${YELLOW}It will then execute a brew update and brew upgrade to ensure" | indent echo -e "${YELLOW} that you are at the latest release of your brew installed packages" | indent echo -e "${YELLOW}dos2unix is installed by brew to correct scripts from hyperledger and composer" | indent - echo -e "${YELLOW}The exec will proceed with checking to ensure you are at Node V6" | indent + echo -e "${YELLOW}The exec will proceed with checking to ensure you are at Node V8" | indent echo -e "${YELLOW} which is required for working with HyperLedger Composer" | indent echo -e "${YELLOW}The script will then install the nodejs SDK for hyperledger and composer" | indent echo -e "${YELLOW}The script will finish by downloading the docker images for hyperledger${RESET}" | indent @@ -254,6 +287,8 @@ do getCurrent + showStep "installing xCode command line tools" + xcode-select --install showStep "checking Brew" check4Brew showStep "checking git" diff --git a/setup_Ubuntu_Part_1.sh b/setup_Ubuntu_Part_1.sh index d1ad18a..9b9b212 100755 --- a/setup_Ubuntu_Part_1.sh +++ b/setup_Ubuntu_Part_1.sh @@ -67,25 +67,41 @@ function checkaptget () sudo apt-get update showStep "upgrading your installed packages" yes | sudo apt-get upgrade - showStep "installing dos2unix exec" + showStep "installing dos2unix exec" sudo apt-get install -y dos2unix + showStep "installing base dev pre-requisites" + sudo apt-get -y install build-essential libssl-dev + showStep "Ensure that CA certificates are installed" + sudo apt-get -y install apt-transport-https ca-certificates + showStep "Add Docker repository key to APT keychain" + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + showStep "Update where APT will search for Docker Packages" + echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu ${UBUNTU_VERSION} stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list + + showStep "Update package lists" + sudo apt-get update + + showStep "Verifies APT is pulling from the correct Repository" + sudo apt-cache policy docker-ce + } -# check to see if nodev6 is installed. install it if it's not already there. +# check to see if nodeV8 is installed. install it if it's not already there. function check4node () { if [[ $NODE_INSTALL == "true" ]]; then which node if [ "$?" -ne 0 ]; then - nodeV6Install + nodeV8Install else - NODE_VERSION=`node --version | grep "v6"` + NODE_VERSION=`node --version | grep "V8"` showStep "Node Version is ${NODE_VERSION}" if [[ ${NODE_VERSION} == "" ]]; then - showStep "${RED}found node $? installed, but not V6. installing Node V6" - nodeV6Install + showStep "${RED}found node $? installed, but not V8. installing Node V8" + nodeV8Install else - showStep "${GREEN}Node V6 already installed" + showStep "${GREEN}Node V8 already installed" fi fi else @@ -95,10 +111,10 @@ function check4node () npm install -g jsdoc } -# install Node V6 -function nodeV6Install() +# install Node V8 +function nodeV8Install() { - showStep "${RED}node not installed. installing Node V6" + showStep "${RED}node not installed. installing Node V8" # Install nvm dependencies showStep "Installing nvm dependencies" sudo apt-get -y install build-essential libssl-dev @@ -113,10 +129,11 @@ function nodeV6Install() [ -s "${NVM_DIR}/bash_completion" ] && . "${NVM_DIR}/bash_completion" showStep "Installing nodeJS" - nvm install v6.12.0 + nvm install --lts - showStep "Configure nvm to use version 6.x" - nvm use v6.12.0 + showStep "Configure nvm to use version 8" + nvm use --lts + nvm alias default 'lts/*' # Install the latest version of npm showStep "Installing npm" @@ -147,13 +164,13 @@ function installNodeDev () if [[ $SDK_INSTALL == "true" ]]; then showStep "The composer-cli contains all the command line operations for developing business networks." npm uninstall -g composer-cli - npm install -g --python=python2.7 composer-cli@0.14.2 + npm install -g --python=python2.7 composer-cli@0.16.0 showStep "The generator-hyperledger-composer is a Yeoman plugin that creates bespoke applications for your business network." npm uninstall -g generator-hyperledger-composer - npm install -g --python=python2.7 generator-hyperledger-composer@0.14.2 + npm install -g --python=python2.7 generator-hyperledger-composer@0.16.0 showStep "The composer-rest-server uses the Hyperledger Composer LoopBack Connector to connect to a business network, extract the models and then present a page containing the REST APIs that have been generated for the model." npm uninstall -g composer-rest-server - npm install -g --python=python2.7 composer-rest-server@0.14.2 + npm install -g --python=python2.7 composer-rest-server@0.16.0 showStep "Yeoman is a tool for generating applications. When combined with the generator-hyperledger-composer component, it can interpret business networks and generate applications based on them." npm install -g --python=python2.7 yo else @@ -228,7 +245,7 @@ function printHeader () echo -e "${YELLOW}The following will be downloaded by this script" | indent echo -e "${YELLOW}dos2unix, to correct scripts from hyperledger and composer" | indent echo -e "${YELLOW}docker for Ubuntu" | indent - echo -e "${YELLOW}The exec will proceed with checking to ensure you are at Node V6" | indent + echo -e "${YELLOW}The exec will proceed with checking to ensure you are at Node V8" | indent echo -e "${YELLOW}which is required for working with HyperLedger Composer" | indent echo -e "${YELLOW}The script will then install the nodejs SDK for hyperledger and composer" | indent echo -e "${YELLOW}The script will finish by requesting that you reboot your system${RESET}" | indent diff --git a/setup_Ubuntu_Part_2.sh b/setup_Ubuntu_Part_2.sh index 4a141e2..f83f983 100755 --- a/setup_Ubuntu_Part_2.sh +++ b/setup_Ubuntu_Part_2.sh @@ -87,13 +87,14 @@ function install_hlf () cd $HLF_INSTALL_PATH ./downloadFabric.sh showStep "installing platform specific binaries for Ubuntu" - curl -sSL https://goo.gl/eYdRbX | bash + curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/release/scripts/bootstrap-1.0.1.sh | bash export PATH=$HLF_INSTALL_PATH/bin:$PATH export HLF_INSTALL_PATH=$HLF_INSTALL_PATH echo 'PATH="'"${HLF_INSTALL_PATH}/bin:$PATH"'"' >>~/.profile echo 'HLF_INSTALL_PATH="'"${HLF_INSTALL_PATH}"'"' >>~/.bashrc echo 'export HLF_INSTALL_PATH' >>~/.bashrc echo 'export FABRIC_VERSION' >>~/.bashrc + sudo chmod +rw ~/.composer else showStep "${RED}skipping HyperLedger Fabric install" fi @@ -156,4 +157,6 @@ do getCurrent showStep "installing hyperledger docker images" install_hlf + showStep "Copying PeerAdmin Credentials" + cp -Rv ~/fabric-tools/fabric-scripts/hlfv1/composer/creds/* ~/.hfc-key-store showStep "installation complete"