Esempio n. 1
0
        public async void ShouldRejectPoItemAndRefundBuyer()
        {
            // Prepare a new PO
            Buyer.Po poAsRequested = await CreateBuyerPoAsync(quoteId : GetRandomInt());

            var signature = poAsRequested.GetSignatureBytes(_contracts.Web3);

            // Test setup - transfer required funds from current Web3 acccount to wallet buyer
            StandardTokenService sts = new StandardTokenService(_contracts.Web3, poAsRequested.CurrencyAddress);
            var totalPoValue         = poAsRequested.GetTotalCurrencyValue();
            var txTransfer           = await sts.TransferRequestAndWaitForReceiptAsync(poAsRequested.BuyerWalletAddress, totalPoValue);

            txTransfer.Status.Value.Should().Be(1);

            // Create PO on-chain
            // NB: this approves token transfer from WALLET BUYER contract (NOT msg.sender == current web3 account) to FUNDING contract
            var txReceiptCreate = await _contracts.Deployment.BuyerWalletService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poAsRequested, signature);

            txReceiptCreate.Status.Value.Should().Be(1);
            _output.WriteLine($"... PO created ...");

            // Get the PO number that was assigned
            var logPoCreated = txReceiptCreate.DecodeAllEvents <PurchaseOrderCreatedLogEventDTO>().FirstOrDefault();

            logPoCreated.Should().NotBeNull();
            var poNumberAsBuilt = logPoCreated.Event.Po.PoNumber;

            // NB: Refunds go to the PO buyer wallet address (not the po buyer address from the PO header, which represents the user)
            // Balance of PO buyer address before refund
            var poBuyerWalletAddressBalanceBefore = await sts.BalanceOfQueryAsync(poAsRequested.BuyerWalletAddress);

            _output.WriteLine($"PO buyer wallet address balance before refund: {await poBuyerWalletAddressBalanceBefore.PrettifyAsync(sts)}");

            // Do the refund (achieved by marking the PO item as rejected)
            var txReceiptPoItemReject = await _contracts.Deployment.SellerAdminService.SetPoItemRejectedRequestAndWaitForReceiptAsync(
                poAsRequested.EShopId, poNumberAsBuilt, PO_ITEM_NUMBER);

            txReceiptPoItemReject.Status.Value.Should().Be(1);
            var poItemValue = poAsRequested.PoItems[PO_ITEM_INDEX].CurrencyValue;

            _output.WriteLine($"... PO item rejected with value {await poItemValue.PrettifyAsync(sts)} ...");

            // Check log exists for Escrow refund
            var logPoItemReject = txReceiptPoItemReject.DecodeAllEvents <PurchaseItemEscrowRefundedLogEventDTO>().FirstOrDefault();

            logPoItemReject.Should().NotBeNull();

            // Balance of PO buyer wallet address after PO item rejection
            var poBuyerWalletAddressBalanceAfter = await sts.BalanceOfQueryAsync(poAsRequested.BuyerWalletAddress);

            _output.WriteLine($"PO buyer wallet address balance after refund: {await poBuyerWalletAddressBalanceAfter.PrettifyAsync(sts)}");

            // Checks
            var diff = poBuyerWalletAddressBalanceAfter - poBuyerWalletAddressBalanceBefore;

            diff.Should().Be(poItemValue, "PO buyer wallet should have increased by value of the PO item");
        }
        public async void ShouldCreatePoAndTransferFunds()
        {
            // Prepare a new PO
            Buyer.Po poAsRequested = await CreateBuyerPoAsync(quoteId : GetRandomInt());

            var signature = poAsRequested.GetSignatureBytes(_contracts.Web3);

            //----------------------------------------------------------
            // BEFORE PO RAISED
            //----------------------------------------------------------
            // Balance of Web3, before test starts (check account running these tests has enough funds to pay for the PO)
            StandardTokenService sts = new StandardTokenService(_contracts.Web3, poAsRequested.CurrencyAddress);
            var totalPoValue         = poAsRequested.GetTotalCurrencyValue();
            var web3AddressBalance   = await sts.BalanceOfQueryAsync(_contracts.Web3.TransactionManager.Account.Address);

            web3AddressBalance.Should().BeGreaterOrEqualTo(totalPoValue, "the Web3 account must be able to pay for whole PO");
            _output.WriteLine($"PO: {poAsRequested.PoNumber}  total value {await totalPoValue.PrettifyAsync(sts)}");

            // Balance of BuyerWallet, before test starts
            var buyerWalletBalance = await sts.BalanceOfQueryAsync(poAsRequested.BuyerWalletAddress);

            _output.WriteLine($"Wallet Buyer balance before test: {await buyerWalletBalance.PrettifyAsync(sts)}");

            // Test setup - transfer required funds from current Web3 acccount to wallet buyer
            var txTransfer = await sts.TransferRequestAndWaitForReceiptAsync(poAsRequested.BuyerWalletAddress, totalPoValue);

            txTransfer.Status.Value.Should().Be(1);

            // Balance of BuyerWallet, before PO raised
            buyerWalletBalance = await sts.BalanceOfQueryAsync(poAsRequested.BuyerWalletAddress);

            _output.WriteLine($"Wallet Buyer balance after receiving funding from Web3 account: {await buyerWalletBalance.PrettifyAsync(sts)}");

            // Balance of Funding, before PO raised
            var fundingBalanceBefore = await sts.BalanceOfQueryAsync(_contracts.Deployment.FundingService.ContractHandler.ContractAddress);

            _output.WriteLine($"Funding balance before PO: {await fundingBalanceBefore.PrettifyAsync(sts)}");

            //----------------------------------------------------------
            // RAISE PO
            //----------------------------------------------------------
            // Create PO on-chain
            // NB this approves token transfer from WALLET BUYER contract (NOT msg.sender == current web3 account) to FUNDING contract
            var txReceiptCreate = await _contracts.Deployment.BuyerWalletService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poAsRequested, signature);

            txReceiptCreate.Status.Value.Should().Be(1);
            _output.WriteLine($"... PO created ...");

            //----------------------------------------------------------
            // AFTER PO RAISED
            //----------------------------------------------------------
            // Balance of BuyerWallet, after PO raised
            buyerWalletBalance = await sts.BalanceOfQueryAsync(poAsRequested.BuyerWalletAddress);

            _output.WriteLine($"Wallet Buyer balance after PO: {await buyerWalletBalance.PrettifyAsync(sts)}");

            // Balance of Funding, after PO raised
            var fundingBalanceAfter = await sts.BalanceOfQueryAsync(_contracts.Deployment.FundingService.ContractHandler.ContractAddress);

            _output.WriteLine($"Funding balance after PO: {await fundingBalanceAfter.PrettifyAsync(sts)}");

            // Check
            var diff = fundingBalanceAfter - fundingBalanceBefore;

            diff.Should().Be(totalPoValue, "funding contract should have increased in value by the PO value");
        }
        public static async Task PrepSendFundsToBuyerWalletForPo(Web3.Web3 fromWeb3, Buyer.Po po)
        {
            // Transfer required funds (tokens) from given Web3 acccount to buyer wallet given on po
            StandardTokenService sts = new StandardTokenService(fromWeb3, po.CurrencyAddress);
            var txTransfer           = await sts.TransferRequestAndWaitForReceiptAsync(po.BuyerWalletAddress, po.GetTotalCurrencyValue());

            txTransfer.Status.Value.Should().Be(1);
        }
Esempio n. 4
0
        public async void ShouldCompletePoItemAndPaySellerLessFees()
        {
            // Prepare a new PO
            Buyer.Po poAsRequested = await CreateBuyerPoAsync(quoteId : GetRandomInt());

            var signature = poAsRequested.GetSignatureBytes(_contracts.Web3);

            // Test setup - transfer required funds from current Web3 acccount to wallet buyer
            BuyerWalletService   bws = _contracts.Deployment.BuyerWalletService;
            SellerAdminService   sas = _contracts.Deployment.SellerAdminService;
            StandardTokenService sts = new StandardTokenService(_contracts.Web3, poAsRequested.CurrencyAddress);
            var totalPoValue         = poAsRequested.GetTotalCurrencyValue();
            var txTransfer           = await sts.TransferRequestAndWaitForReceiptAsync(poAsRequested.BuyerWalletAddress, totalPoValue);

            txTransfer.Status.Value.Should().Be(1);

            // Create PO on-chain
            // NB: this approves token transfer from BUYER WALLET contract (NOT msg.sender == current web3 account) to FUNDING contract
            var txReceiptCreate = await bws.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poAsRequested, signature);

            txReceiptCreate.Status.Value.Should().Be(1);
            _output.WriteLine($"... PO created ...");

            // Get the PO number that was assigned
            var logPoCreated = txReceiptCreate.DecodeAllEvents <PurchaseOrderCreatedLogEventDTO>().FirstOrDefault();

            logPoCreated.Should().NotBeNull();
            var poNumberAsBuilt = logPoCreated.Event.Po.PoNumber;

            // NB: Payment goes to the SellerAdmin address
            var sellerAdminBalanceBefore = await sts.BalanceOfQueryAsync(_contracts.Deployment.SellerAdminService.ContractHandler.ContractAddress);

            _output.WriteLine($"SellerAdmin balance before completion: {await sellerAdminBalanceBefore.PrettifyAsync(sts)}");

            // Process PO item through to completion (completion step will release funds)
            // Mark PO item as Accepted
            var txReceiptAccept = await sas.SetPoItemAcceptedRequestAndWaitForReceiptAsync(
                poAsRequested.EShopId, poNumberAsBuilt, PO_ITEM_NUMBER, SALES_ORDER_NUMBER, SALES_ORDER_ITEM);

            txReceiptAccept.Status.Value.Should().Be(1);

            // Mark PO item as Ready for Goods Issue
            var txReceiptReadyForGI = await sas.SetPoItemReadyForGoodsIssueRequestAndWaitForReceiptAsync(
                poAsRequested.EShopId, poNumberAsBuilt, PO_ITEM_NUMBER);

            txReceiptReadyForGI.Status.Value.Should().Be(1);

            // Mark PO item as Goods Issued
            var txReceiptGI = await sas.SetPoItemGoodsIssuedRequestAndWaitForReceiptAsync(
                poAsRequested.EShopId, poNumberAsBuilt, PO_ITEM_NUMBER);

            txReceiptGI.Status.Value.Should().Be(1);

            // Mark PO item as Goods Received by the Buyer (so we don't have to wait 30 days)
            var txReceiptGR = await bws.SetPoItemGoodsReceivedRequestAndWaitForReceiptAsync(
                poAsRequested.EShopId, poNumberAsBuilt, PO_ITEM_NUMBER);

            txReceiptGR.Status.Value.Should().Be(1);

            // Mark PO item as Complete
            var txReceiptCompleted = await sas.SetPoItemCompletedRequestAndWaitForReceiptAsync(
                poAsRequested.EShopId, poNumberAsBuilt, PO_ITEM_NUMBER);

            txReceiptCompleted.Status.Value.Should().Be(1);
            var poItemValue = poAsRequested.PoItems[PO_ITEM_INDEX].CurrencyValue;

            _output.WriteLine($"... PO item completed with value {await poItemValue.PrettifyAsync(sts)} ...");

            // Check log exists for Escrow release
            var logPoItemCompleted = txReceiptCompleted.DecodeAllEvents <PurchaseItemEscrowReleasedLogEventDTO>().FirstOrDefault();

            logPoItemCompleted.Should().NotBeNull();

            // Balance of PO buyer address after PO item rejection
            var sellerAdminBalanceAfter = await sts.BalanceOfQueryAsync(_contracts.Deployment.SellerAdminService.ContractHandler.ContractAddress);

            _output.WriteLine($"SellerAdmin balance after completion: {await sellerAdminBalanceAfter.PrettifyAsync(sts)}");

            // Checks must include fees
            var feeBasisPoints = await _contracts.Deployment.PurchasingService.GetFeeBasisPointsQueryAsync();

            var fee  = poItemValue * feeBasisPoints / 10000;
            var diff = sellerAdminBalanceAfter - sellerAdminBalanceBefore;

            diff.Should().Be(poItemValue - fee, "SellerAdmin contract address should increase by PO item value minus fee");
        }