Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PartTemplate work #293

Merged
merged 7 commits into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Domain.LinnApps/Parts/PartTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public class PartTemplate

public int? NextNumber { get; set; }

public string AllowVariants { get; set; }

public string Variants { get; set; }

public string AccountingCompany { get; set; }

public string ProductCode { get; set; }
Expand All @@ -22,6 +26,8 @@ public class PartTemplate

public string BomType { get; set; }

public string RmFg { get; set; }

public string AssemblyTechnology { get; set; }

public string AllowPartCreation { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions src/Facade/ResourceBuilders/PartTemplateResourceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ public PartTemplateResource Build(PartTemplate model)
HasDataSheet = model.HasDataSheet,
HasNumberSequence = model.HasNumberSequence,
NextNumber = model.NextNumber,
AllowVariants = model.AllowVariants,
Variants = model.Variants,
AccountingCompany = model.AccountingCompany,
ProductCode = model.ProductCode,
StockControlled = model.StockControlled,
LinnProduced = model.LinnProduced,
RmFg = model.RmFg,
BomType = model.BomType,
AssemblyTechnology = model.AssemblyTechnology,
AllowPartCreation = model.AllowPartCreation,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember you can set the "self" linkrel in GetLocation down below

Expand Down
39 changes: 37 additions & 2 deletions src/Facade/Services/PartTemplateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,47 @@ public PartTemplateService(IRepository<PartTemplate, string> repository, ITransa

protected override PartTemplate CreateFromResource(PartTemplateResource resource)
{
throw new NotImplementedException();
var partTemplate = new PartTemplate
{
PartRoot = resource.PartRoot,
Description = resource.Description,
HasDataSheet = resource.HasDataSheet,
HasNumberSequence = resource.HasNumberSequence,
NextNumber = resource.NextNumber,
AllowVariants = resource.AllowVariants,
Variants = resource.Variants,
AccountingCompany = resource.AccountingCompany,
ProductCode = resource.ProductCode,
StockControlled = resource.StockControlled,
LinnProduced = resource.LinnProduced,
BomType = resource.BomType,
RmFg = resource.RmFg,
AssemblyTechnology = resource.AssemblyTechnology,
AllowPartCreation = resource.AllowPartCreation,
ParetoCode = resource.ParetoCode
};

return partTemplate;
}

protected override void UpdateFromResource(PartTemplate entity, PartTemplateResource updateResource)
{
throw new NotImplementedException();
entity.PartRoot = updateResource.PartRoot;
entity.Description = updateResource.Description;
entity.HasDataSheet = updateResource.HasDataSheet;
entity.HasNumberSequence = updateResource.HasNumberSequence;
entity.NextNumber = updateResource.NextNumber;
entity.AllowVariants = updateResource.AllowVariants;
entity.Variants = updateResource.Variants;
entity.AccountingCompany = updateResource.AccountingCompany;
entity.ProductCode = updateResource.ProductCode;
entity.StockControlled = updateResource.StockControlled;
entity.LinnProduced = updateResource.LinnProduced;
entity.BomType = updateResource.BomType;
entity.RmFg = updateResource.RmFg;
entity.AssemblyTechnology = updateResource.AssemblyTechnology;
entity.AllowPartCreation = updateResource.AllowPartCreation;
entity.ParetoCode = updateResource.ParetoCode;
}

protected override Expression<Func<PartTemplate, bool>> SearchExpression(string searchTerm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public IQueryable<PartTemplate> FindAll()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember to take off AsNoTracking up above if we're amending these things now

public void Add(PartTemplate entity)
{
throw new NotImplementedException();
this.serviceDbContext.PartTemplates.Add(entity);
}

public void Remove(PartTemplate entity)
Expand Down
3 changes: 3 additions & 0 deletions src/Persistence.LinnApps/ServiceDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -686,11 +686,14 @@ private void BuildPartTemplates(ModelBuilder builder)
e.Property(p => p.StockControlled).HasColumnName("STOCK_CONTROLLED").HasMaxLength(1);
e.Property(p => p.LinnProduced).HasColumnName("LINN_PRODUCED").HasMaxLength(1);
e.Property(p => p.BomType).HasColumnName("BOM_TYPE").HasMaxLength(1);
e.Property(p => p.RmFg).HasColumnName("RM_FG").HasMaxLength(1);
e.Property(p => p.ParetoCode).HasColumnName("PARETO_CODE").HasMaxLength(2);
e.Property(p => p.AssemblyTechnology).HasColumnName("ASSEMBLY_TECHNOLOGY");
e.Property(p => p.HasDataSheet).HasColumnName("HAS_DATASHEET").HasMaxLength(1);
e.Property(p => p.HasNumberSequence).HasColumnName("NUMBER_SEQUENCE").HasMaxLength(1);
e.Property(p => p.NextNumber).HasColumnName("NEXT_NUMBER");
e.Property(p => p.AllowVariants).HasColumnName("ALLOW_VARIANTS").HasMaxLength(1);
e.Property(p => p.Variants).HasColumnName("VARIANTS").HasMaxLength(255);
e.Property(p => p.ProductCode).HasColumnName("PRODUCT_CODE").HasMaxLength(10);
e.Property(p => p.AllowPartCreation).HasColumnName("ALLOW_PART_CREATION").HasMaxLength(1);
e.Property(p => p.AccountingCompany).HasColumnName("ACCOUNTING_COMPANY");
Expand Down
6 changes: 6 additions & 0 deletions src/Resources/Parts/PartTemplateResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public class PartTemplateResource

public int? NextNumber { get; set; }

public string AllowVariants { get; set; }

public string Variants { get; set; }

public string AccountingCompany { get; set; }

public string ProductCode { get; set; }
Expand All @@ -22,6 +26,8 @@ public class PartTemplateResource

public string BomType { get; set; }

public string RmFg { get; set; }

public string AssemblyTechnology { get; set; }

public string AllowPartCreation { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions src/Service.Host/client/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const rootProductsActionTypes = makeActionTypes(itemTypes.rootProducts.ac

export const partCategoriesActionTypes = makeActionTypes(itemTypes.partCategories.actionType);

export const partTemplateActionTypes = makeActionTypes(itemTypes.partTemplate.actionType);

export const partTemplatesActionTypes = makeActionTypes(itemTypes.partTemplates.actionType);

export const partLiveTestActionTypes = makeActionTypes(itemTypes.partLiveTest.actionType);
Expand Down
12 changes: 12 additions & 0 deletions src/Service.Host/client/src/actions/partTemplateActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { UpdateApiActions } from '@linn-it/linn-form-components-library';
import { partTemplateActionTypes as actionTypes } from './index';
import * as itemTypes from '../itemTypes';
import config from '../config';

export default new UpdateApiActions(
itemTypes.partTemplate.item,
itemTypes.partTemplate.actionType,
itemTypes.partTemplate.uri,
actionTypes,
config.appRoot
);
4 changes: 3 additions & 1 deletion src/Service.Host/client/src/containers/parts/Part.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import partCategoriesSelectors from '../../selectors/partCategoriesSelectors';
import sernosSequencesSelectors from '../../selectors/sernosSequencesSelectors';
import suppliersSelectors from '../../selectors/suppliersSelectors';
import unitsOfMeasureSelectors from '../../selectors/unitsOfMeasureSelectors';
import partTemplateActions from '../../actions/partTemplateActions';
import partTemplatesActions from '../../actions/partTemplatesActions';
import partTemplateSelectors from '../../selectors/partTemplatesSelectors';
import partTemplatesSelectors from '../../selectors/partTemplatesSelectors';
import { getPrivileges, getUserName, getUserNumber } from '../../selectors/userSelectors';
import * as itemTypes from '../../itemTypes';
import partLiveTestSelectors from '../../selectors/partLiveTestSelectors';
Expand Down Expand Up @@ -49,7 +51,7 @@ const mapStateToProps = (state, { match, location }) => ({
userName: getUserName(state),
userNumber: getUserNumber(state),
templateName: queryString.parse(location?.search)?.template,
partTemplates: partTemplateSelectors.getItems(state),
partTemplates: partTemplatesSelectors.getItems(state),
liveTest: creating(match) ? null : partLiveTestSelectors.getItem(state),
partsSearchResults: partsSelectors.getSearchItems(state),
previousPaths: getPreviousPaths(state)
Expand Down
5 changes: 4 additions & 1 deletion src/Service.Host/client/src/containers/parts/Parts.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import partsSelectors from '../../selectors/partsSelectors';
import { getPrivileges } from '../../selectors/userSelectors';
import partTemplatesActions from '../../actions/partTemplatesActions';
import partTemplatesSelectors from '../../selectors/partTemplatesSelectors';
import partTemplateActions from '../../actions/partTemplatesActions';
import partTemplateSelectors from '../../selectors/partTemplatesSelectors';

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need these extra action creators and selectors in the parts container?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also just realised I never got you set up witht the linter which would have complained about this most likely. Give me a shout today and I can try and remember what we need to do to get it working

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can talk about it after stand up if you're about

const mapStateToProps = (state, { match }) => ({
linkToSources: match?.url?.endsWith('/sources'),
items: partsSelectors.getSearchItems(state),
loading: partsSelectors.getSearchLoading(state),
privileges: getPrivileges(state),
partTemplates: partTemplatesSelectors.getItems(state)
partTemplates: partTemplatesSelectors.getItems(state),
partTemplate: partTemplateSelectors.getItem(state)
});

const initialise = () => dispatch => {
Expand Down
6 changes: 6 additions & 0 deletions src/Service.Host/client/src/itemTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export const partCategories = new ItemType(
'/inventory/part-categories'
);

export const partTemplate = new ItemType(
'partTemplate',
'PART_TEMPLATE',
'/inventory/part-templates'
);

export const partTemplates = new ItemType(
'partTemplates',
'PART_TEMPLATES',
Expand Down
2 changes: 2 additions & 0 deletions src/Service.Host/client/src/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import accountingCompanies from './accountingCompanies';
import nominal from './nominal';
import parts from './parts/parts';
import part from './parts/part';
import partTemplate from './parts/partTemplate';
import partTemplates from './parts/partTemplates';
import partLiveTest from './parts/partLiveTest';
import partCategories from './partCategories';
Expand Down Expand Up @@ -202,6 +203,7 @@ const rootReducer = history =>
partLiveTest,
parts,
partStorageTypes,
partTemplate,
partTemplates,
pickItemsAllocation,
ports,
Expand Down
14 changes: 14 additions & 0 deletions src/Service.Host/client/src/reducers/parts/partTemplate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { collectionStoreFactory } from '@linn-it/linn-form-components-library';
import { partTemplateActionTypes as actionTypes } from '../../actions';
import * as itemTypes from '../../itemTypes';

const defaultState = {
loading: false,
items: []
};

export default collectionStoreFactory(
itemTypes.partTemplate.actionType,
actionTypes,
defaultState
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { ItemSelectors } from '@linn-it/linn-form-components-library';
import * as itemTypes from '../itemTypes';

export default new ItemSelectors(itemTypes.partTemplate.item);
30 changes: 30 additions & 0 deletions src/Service/Modules/PartsModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ public PartsModule(

this.partTemplateService = partTemplateService;
this.Get("/inventory/part-templates", _ => this.GetPartTemplates());
this.Get("/inventory/part-templates/{id}", parameters => this.GetPartTemplate(parameters.id));
this.Put("/inventory/part-templates/{id}", parameters => this.UpdatePartTemplate(parameters.id));
this.Post("/inventory/part-templates", parameters => this.AddPartTemplate());

this.productAnalysisCodeService = productAnalysisCodeService;
this.Get("inventory/product-analysis-codes", _ => this.GetProductAnalysisCodes());
Expand Down Expand Up @@ -230,6 +233,33 @@ private object GetPartCategories()
.WithMediaRangeModel("text/html", ApplicationSettings.Get);
}

private object AddPartTemplate()
{
this.RequiresAuthentication();
var resource = this.Bind<PartTemplateResource>();
var result = this.partTemplateService.Add(resource);
return this.Negotiate.WithStatusCode(HttpStatusCode.Created)
.WithModel(result)
.WithMediaRangeModel("text/html", ApplicationSettings.Get)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to handle html here because it will never be requested in a PUT or a POST

.WithView("Index");
}

private object GetPartTemplate(string id)
{
var result = this.partTemplateService.GetById(id);
return this.Negotiate.WithModel(result)
.WithMediaRangeModel("text/html", ApplicationSettings.Get);
}

private object UpdatePartTemplate(string id)
{
this.RequiresAuthentication();
var resource = this.Bind<PartTemplateResource>();
var result = this.partTemplateService.Update(id, resource);
return this.Negotiate.WithModel(result)
.WithMediaRangeModel("text/html", ApplicationSettings.Get);
}

private object GetPartTemplates()
{
var result = this.partTemplateService.GetAll();
Expand Down
15 changes: 15 additions & 0 deletions src/Service/ResponseProcessors/PartTemplateResponseProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Linn.Stores.Service.ResponseProcessors
{
using System.Collections.Generic;
using Linn.Common.Facade;
using Linn.Common.Nancy.Facade;
using Linn.Stores.Domain.LinnApps.Parts;

public class PartTemplateResponseProcessor : JsonResponseProcessor<PartTemplate>
{
public PartTemplateResponseProcessor(IResourceBuilder<PartTemplate> resourceBuilder)
: base(resourceBuilder, "linnapps-part-templates", 1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be the singular. "linnapps-part-template"

{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ public void EstablishContext()
with.ResponseProcessor<AssemblyTechnologiesResponseProcessor>();
with.ResponseProcessor<DecrementRulesResponseProcessor>();
with.ResponseProcessor<ProductAnalysisCodesResponseProcessor>();
with.ResponseProcessor<PartTemplateResponseProcessor>();
with.ResponseProcessor<PartTemplatesResponseProcessor>();
with.ResponseProcessor<PartLiveTestResponseProcessor>();
with.ResponseProcessor<MechPartSourceResponseProcessor>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace Linn.Stores.Service.Tests.PartsModuleSpecs
{
using System.Collections.Generic;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these usings needed for the get by id?

using System.Linq;

using FluentAssertions;

using Linn.Common.Facade;
using Linn.Stores.Domain.LinnApps.Parts;
using Linn.Stores.Resources.Parts;

using Nancy;
using Nancy.Testing;

using NSubstitute;

using NUnit.Framework;

public class WhenGettingPartTemplatesById : ContextBase
{
[SetUp]
public void SetUp()
{
var a = new PartTemplate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd use a more descriptive variable name than a

{
PartRoot = "PARTTEMP"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be nice to declare "PARTTEMP" into a string field and then you can reference it against all the tests which avoids typos and also makes it clear what's being tested

};

this.PartTemplateService.GetById(a.PartRoot)
.Returns(new SuccessResult<PartTemplate>(a));

this.Response = this.Browser.Get(
"/inventory/part-templates/PARTTEMP",
with =>
{
with.Header("Accept", "application/json");
}).Result;
}

[Test]
public void ShouldReturnOk()
{
this.Response.StatusCode.Should().Be(HttpStatusCode.OK);
}

[Test]
public void ShouldCallService()
{
this.PartTemplateService.Received().GetById("PARTTEMP");
}

[Test]
public void ShouldReturnResource()
{
var resource = this.Response.Body.DeserializeJson<PartTemplateResource>();
resource.PartRoot.Should().Be("PARTTEMP");
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we tend to add a newline at the end of files to stop github complaining at us