diff --git a/src/Domain.LinnApps/ExportRsn.cs b/src/Domain.LinnApps/ExportRsn.cs index ccb093e50..b952fb57d 100644 --- a/src/Domain.LinnApps/ExportRsn.cs +++ b/src/Domain.LinnApps/ExportRsn.cs @@ -25,5 +25,15 @@ public class ExportRsn public string CountryName { get; set; } public string AccountType { get; set; } + + public string InvoiceDescription { get; set; } + + public int? Weight { get; set; } + + public int? Height { get; set; } + + public int? Depth { get; set; } + + public int? Width { get; set; } } } diff --git a/src/Facade/ResourceBuilders/ExportRsnResourceBuilder.cs b/src/Facade/ResourceBuilders/ExportRsnResourceBuilder.cs index 014ceafa6..d9ef961d1 100644 --- a/src/Facade/ResourceBuilders/ExportRsnResourceBuilder.cs +++ b/src/Facade/ResourceBuilders/ExportRsnResourceBuilder.cs @@ -20,7 +20,12 @@ public ExportRsnResource Build(ExportRsn exportRsn) OutletNumber = exportRsn.OutletNumber, Country = exportRsn.Country, CountryName = exportRsn.CountryName, - AccountType = exportRsn.AccountType + AccountType = exportRsn.AccountType, + InvoiceDescription = exportRsn.InvoiceDescription, + Depth = exportRsn.Depth, + Height = exportRsn.Height, + Weight = exportRsn.Weight, + Width = exportRsn.Width }; } diff --git a/src/Facade/Services/ExportRsnService.cs b/src/Facade/Services/ExportRsnService.cs index 38438845e..7edfdc9bb 100644 --- a/src/Facade/Services/ExportRsnService.cs +++ b/src/Facade/Services/ExportRsnService.cs @@ -1,6 +1,7 @@ namespace Linn.Stores.Facade.Services { using System.Collections.Generic; + using System.Linq; using Linn.Common.Facade; using Linn.Common.Persistence; using Linn.Stores.Domain.LinnApps; @@ -14,16 +15,28 @@ public ExportRsnService(IQueryRepository repository) this.repository = repository; } - public IResult> SearchRsns(int accountId, int? outletNumber) + public IEnumerable FindMatchingRSNs(IEnumerable rsns, string searchTerm) + { + if (string.IsNullOrEmpty(searchTerm)) + { + return rsns; + } + + return rsns.ToList().Where(r => r.RsnNumber.ToString().Contains(searchTerm)); + } + + public IResult> SearchRsns(int accountId, int? outletNumber, string searchTerm) { if (outletNumber != null) { return new SuccessResult>( - this.repository.FilterBy(rsn => rsn.AccountId == accountId && rsn.OutletNumber == outletNumber)); + this.FindMatchingRSNs(this.repository.FilterBy(rsn => rsn.AccountId == accountId && rsn.OutletNumber == outletNumber), searchTerm)); } return new SuccessResult>( - this.repository.FilterBy(rsn => rsn.AccountId == accountId)); + this.FindMatchingRSNs(this.repository.FilterBy(rsn => rsn.AccountId == accountId),searchTerm)); } + + } } diff --git a/src/Facade/Services/IExportRsnService.cs b/src/Facade/Services/IExportRsnService.cs index 868dde742..6dbb8fd85 100644 --- a/src/Facade/Services/IExportRsnService.cs +++ b/src/Facade/Services/IExportRsnService.cs @@ -7,6 +7,6 @@ public interface IExportRsnService { - IResult> SearchRsns(int accountId, int? outletNumber); + IResult> SearchRsns(int accountId, int? outletNumber, string searchTerm); } } \ No newline at end of file diff --git a/src/Persistence.LinnApps/ServiceDbContext.cs b/src/Persistence.LinnApps/ServiceDbContext.cs index b75647aa9..24fe30933 100644 --- a/src/Persistence.LinnApps/ServiceDbContext.cs +++ b/src/Persistence.LinnApps/ServiceDbContext.cs @@ -1381,6 +1381,11 @@ private void QueryExportRsns(ModelBuilder builder) q.Property(e => e.Country).HasColumnName("COUNTRY").HasMaxLength(2); q.Property(e => e.CountryName).HasColumnName("COUNTRY_NAME").HasMaxLength(50); q.Property(e => e.AccountType).HasColumnName("ACCOUNT_TYPE").HasMaxLength(10); + q.Property(e => e.InvoiceDescription).HasColumnName("INVOICE_DESCRIPTION").HasMaxLength(50); + q.Property(e => e.Weight).HasColumnName("WEIGHT"); + q.Property(e => e.Height).HasColumnName("HEIGHT"); + q.Property(e => e.Depth).HasColumnName("DEPTH"); + q.Property(e => e.Width).HasColumnName("WIDTH"); } private void QuerySalesAccounts(ModelBuilder builder) diff --git a/src/Resources/ExportRsnResource.cs b/src/Resources/ExportRsnResource.cs index 06aacb2e8..eec39024c 100644 --- a/src/Resources/ExportRsnResource.cs +++ b/src/Resources/ExportRsnResource.cs @@ -23,5 +23,15 @@ public class ExportRsnResource public string CountryName { get; set; } public string AccountType { get; set; } + + public string InvoiceDescription { get; set; } + + public int? Weight { get; set; } + + public int? Height { get; set; } + + public int? Depth { get; set; } + + public int? Width { get; set; } } } \ No newline at end of file diff --git a/src/Resources/RequestResources/ExportRsnSearchRequestResource.cs b/src/Resources/RequestResources/ExportRsnSearchRequestResource.cs index 1cce77c7d..0b8cccc68 100644 --- a/src/Resources/RequestResources/ExportRsnSearchRequestResource.cs +++ b/src/Resources/RequestResources/ExportRsnSearchRequestResource.cs @@ -5,5 +5,7 @@ public class ExportRsnSearchRequestResource public int AccountId { get; set; } public int? OutletNumber { get; set; } + + public string SearchTerm { get; set; } } } \ No newline at end of file diff --git a/src/Service.Host/client/src/components/consignments/Consignment.js b/src/Service.Host/client/src/components/consignments/Consignment.js index 4dc634432..9364870ea 100644 --- a/src/Service.Host/client/src/components/consignments/Consignment.js +++ b/src/Service.Host/client/src/components/consignments/Consignment.js @@ -79,7 +79,11 @@ function Consignment({ saveDocumentsClearData, salesOutlets, salesOutletsLoading, - getSalesOutlets + getSalesOutlets, + rsnsSearchResults, + rsnsSearchLoading, + searchRsns, + clearRsnsSearch }) { const [dialogOpen, setDialogOpen] = useState(false); const [termsMessage, setTermsMessage] = useState(false); @@ -90,6 +94,7 @@ function Consignment({ const [saveDisabled, setSaveDisabled] = useState(false); const [showCartonLabel, setShowCartonLabel] = useState(false); const [showNewCartonDialog, setShowNewCartonDialog] = useState(false); + const [showNewRSNDialog, setShowNewRSNDialog] = useState(false); const [cartonLabelOptions, setCartonLabelOptions] = useState({ numberOfCopies: 1, firstItem: 1, @@ -457,6 +462,20 @@ function Consignment({ depth: selectedCarton.depth }); } + } else if (propertyName === 'rsnNumber') { + const selectedRSN = rsnsSearchResults.find(a => a.rsnNumber === newValue); + if (selectedRSN) { + setNewCarton({ + ...newCarton, + rsnNumber: selectedRSN.rsnNumber, + itemDescription: selectedRSN.invoiceDescription, + height: selectedRSN.height, + depth: selectedRSN.depth, + width: selectedRSN.width, + weight: selectedRSN.weight, + quantity: selectedRSN.quantity + }); + } } }; @@ -475,6 +494,18 @@ function Consignment({ setEditableItems(items); }; + const addRSN = () => { + const maxCarton = getMaxCarton(); + const maxItem = getMaxItemNumber(); + + setNewCarton({ + itemNumber: maxItem ? maxItem + 1 : 1, + containerNumber: maxCarton ? maxCarton + 1 : 1 + }); + + setShowNewRSNDialog(true); + }; + const handlePrintDocuments = () => { printDocumentsClearData(); printDocuments({ consignmentId: item.consignmentId, userNumber }); @@ -494,10 +525,23 @@ function Consignment({ })); }; + const rsnSearchResult = () => { + return rsnsSearchResults?.map(rsn => ({ + ...rsn, + name: rsn.rsnNumber, + description: rsn.invoiceDescription, + id: rsn.rsnNumber + })); + }; + const handleOnSelect = selectedCartonType => { updateNewCartonField('containerType', selectedCartonType.cartonTypeName); }; + const handleOnSelectRsn = selectedRsn => { + updateNewCartonField('rsnNumber', selectedRsn.rsnNumber); + }; + return (
@@ -707,6 +751,14 @@ function Consignment({ > Add Carton + + + + + + + + +
); @@ -1127,7 +1335,11 @@ Consignment.propTypes = { saveDocumentsClearData: PropTypes.func.isRequired, salesOutlets: PropTypes.arrayOf(PropTypes.shape({})), salesOutletsLoading: PropTypes.bool, - getSalesOutlets: PropTypes.func.isRequired + getSalesOutlets: PropTypes.func.isRequired, + rsnsSearchResults: PropTypes.arrayOf(PropTypes.shape({})), + rsnsSearchLoading: PropTypes.bool, + searchRsns: PropTypes.func.isRequired, + clearRsnsSearch: PropTypes.func.isRequired }; Consignment.defaultProps = { @@ -1160,7 +1372,9 @@ Consignment.defaultProps = { saveDocumentsWorking: false, saveDocumentsResult: null, salesOutlets: [], - salesOutletsLoading: false + salesOutletsLoading: false, + rsnsSearchResults: [], + rsnsSearchLoading: false }; export default Consignment; diff --git a/src/Service.Host/client/src/containers/consignments/Consignment.js b/src/Service.Host/client/src/containers/consignments/Consignment.js index 70e698e10..0e13e1f71 100644 --- a/src/Service.Host/client/src/containers/consignments/Consignment.js +++ b/src/Service.Host/client/src/containers/consignments/Consignment.js @@ -36,6 +36,8 @@ import saveConsignmentDocumentsActions from '../../actions/saveConsignmentDocume import saveConsignmentDocumentsSelectors from '../../selectors/saveConsignmentDocumentsSelectors'; import salesOutletsSelectors from '../../selectors/salesOutletsSelectors'; import salesOutletsActions from '../../actions/salesOutletsActions'; +import exportRsnsActions from '../../actions/exportRsnsActions'; +import exportRsnsSelectors from '../../selectors/exportRsnsSelectors'; const getOptions = ownProps => { const options = queryString.parse(ownProps.location.search); @@ -95,7 +97,9 @@ const mapStateToProps = (state, ownProps) => ({ saveDocumentsWorking: saveConsignmentDocumentsSelectors.getWorking(state), saveDocumentsResult: saveConsignmentDocumentsSelectors.getData(state), salesOutlets: salesOutletsSelectors.getSearchItems(state), - salesOutletsLoading: salesOutletsSelectors.getLoading(state) + salesOutletsLoading: salesOutletsSelectors.getLoading(state), + rsnsSearchResults: exportRsnsSelectors.getSearchItems(state), + rsnsSearchLoading: exportRsnsSelectors.getSearchLoading(state) }); const mapDispatchToProps = { @@ -122,7 +126,9 @@ const mapDispatchToProps = { clearCartonTypesSearch: cartonTypesActions.clearSearch, saveDocuments: saveConsignmentDocumentsActions.requestProcessStart, saveDocumentsClearData: saveConsignmentDocumentsActions.clearProcessData, - getSalesOutlets: salesOutletsActions.searchWithOptions + getSalesOutlets: salesOutletsActions.searchWithOptions, + searchRsns: exportRsnsActions.searchWithOptions, + clearRsnsSearch: exportRsnsActions.clearSearch }; export default connect(mapStateToProps, mapDispatchToProps)(initialiseOnMount(Consignment)); diff --git a/src/Service/Modules/ExportRsnModule.cs b/src/Service/Modules/ExportRsnModule.cs index bac99b67e..4c256744f 100644 --- a/src/Service/Modules/ExportRsnModule.cs +++ b/src/Service/Modules/ExportRsnModule.cs @@ -21,7 +21,7 @@ private object GetRsns() { var resource = this.Bind(); - var results = this.exportRsnService.SearchRsns(resource.AccountId, resource.OutletNumber); + var results = this.exportRsnService.SearchRsns(resource.AccountId, resource.OutletNumber, resource.SearchTerm); return this.Negotiate .WithModel(results) diff --git a/tests/Integration/Service.Tests/ExportRsnModuleSpecs/WhenGettingRsns.cs b/tests/Integration/Service.Tests/ExportRsnModuleSpecs/WhenGettingRsns.cs index 6780c69a3..7379145fb 100644 --- a/tests/Integration/Service.Tests/ExportRsnModuleSpecs/WhenGettingRsns.cs +++ b/tests/Integration/Service.Tests/ExportRsnModuleSpecs/WhenGettingRsns.cs @@ -24,7 +24,7 @@ public void SetUp() var rsn1 = new ExportRsn { RsnNumber = 1, AccountId = 123, OutletNumber = 1 }; var rsn2 = new ExportRsn { RsnNumber = 2, AccountId = 123, OutletNumber = 1 }; - this.ExportRsnService.SearchRsns(123, 1) + this.ExportRsnService.SearchRsns(123, 1, "1") .Returns(new SuccessResult>(new List { rsn1, rsn2 })); this.Response = this.Browser.Get( @@ -34,6 +34,7 @@ public void SetUp() with.Header("Accept", "application/json"); with.Query("accountId", "123"); with.Query("outletNumber", "1"); + with.Query("searchTerm", "1"); }).Result; } @@ -46,7 +47,7 @@ public void ShouldReturnOk() [Test] public void ShouldCallService() { - this.ExportRsnService.Received().SearchRsns(123, 1); + this.ExportRsnService.Received().SearchRsns(123, 1, "1"); } [Test] diff --git a/tests/Unit/Facade.Tests/ExportRsnService/WhenGettingExportRsns.cs b/tests/Unit/Facade.Tests/ExportRsnService/WhenGettingExportRsns.cs index 44c19c165..834a8f111 100644 --- a/tests/Unit/Facade.Tests/ExportRsnService/WhenGettingExportRsns.cs +++ b/tests/Unit/Facade.Tests/ExportRsnService/WhenGettingExportRsns.cs @@ -25,7 +25,7 @@ public void SetUp() this.ExportRsnRepository.FilterBy(Arg.Any>>()).Returns(rsns.AsQueryable()); - this.result = this.Sut.SearchRsns(123, null); + this.result = this.Sut.SearchRsns(123, null, string.Empty); } [Test] diff --git a/tests/Unit/Facade.Tests/ExportRsnService/WhenGettingExportRsnsWithNumber.cs b/tests/Unit/Facade.Tests/ExportRsnService/WhenGettingExportRsnsWithNumber.cs new file mode 100644 index 000000000..55e3692fd --- /dev/null +++ b/tests/Unit/Facade.Tests/ExportRsnService/WhenGettingExportRsnsWithNumber.cs @@ -0,0 +1,52 @@ +namespace Linn.Stores.Facade.Tests.ExportRsnService +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Linq.Expressions; + + using FluentAssertions; + + using Linn.Common.Facade; + using Linn.Stores.Domain.LinnApps; + + using NSubstitute; + + using NUnit.Framework; + + public class WhenGettingExportRsnsWithNumber : ContextBase + { + private IResult> result; + + [SetUp] + public void SetUp() + { + var rsns = new List { new ExportRsn { RsnNumber = 10 }, new ExportRsn { RsnNumber = 20 }, new ExportRsn { RsnNumber = 30 } }; + + this.ExportRsnRepository.FilterBy(Arg.Any>>()).Returns(rsns.AsQueryable()); + + this.result = this.Sut.SearchRsns(123, null, "2"); + } + + [Test] + + public void ShouldSearch() + { + this.ExportRsnRepository.Received().FilterBy(Arg.Any>>()); + } + + [Test] + public void ShouldReturnSuccess() + { + this.result.Should().BeOfType>>(); + } + + [Test] + public void ShouldReturnOneMatchRSN() + { + ((SuccessResult>)this.result).Data.Count().Should().Be(1); + var rsn = ((SuccessResult>)this.result).Data.FirstOrDefault(); + rsn.RsnNumber.Should().Be(20); + } + } +} \ No newline at end of file