public async void ShouldNotBeAbleToSetPoItemStatusWhenNotSellerAdminOwner() { // Try to set a PO item status by a non-authorised user, it should fail // Prepare a new PO and create it Buyer.Po poAsRequested = await CreateBuyerPoAsync(quoteId : GetRandomInt()); var signature = poAsRequested.GetSignatureBytes(_contracts.Web3); await PrepSendFundsToBuyerWalletForPo(_contracts.Web3, poAsRequested); var txReceipt = await _contracts.Deployment.BuyerWalletService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poAsRequested, signature); txReceipt.Status.Value.Should().Be(1); // Check PO create events var logPoCreated = txReceipt.DecodeAllEvents <PurchaseOrderCreatedLogEventDTO>().FirstOrDefault(); logPoCreated.Should().NotBeNull(); var poNumberAsBuilt = logPoCreated.Event.Po.PoNumber; // Attempt to mark PO item as accepted using preexisting SellerAdmin contract, but with tx executed by the non-authorised ("secondary") user var wss = new SellerAdminService(_contracts.Web3SecondaryUser, _contracts.Deployment.SellerAdminService.ContractHandler.ContractAddress); Func <Task> act = async() => await wss.SetPoItemAcceptedRequestAndWaitForReceiptAsync( poAsRequested.EShopId, poNumberAsBuilt, 1, "SalesOrder1", "Item1"); act.Should().Throw <SmartContractRevertException>().WithMessage(AUTH_EXCEPTION_ONLY_OWNER); }
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"); }