using Microsoft.AspNetCore.Mvc; using PartSource.Data.Dtos; using PartSource.Data.Models; using PartSource.Data.Nexpart; using PartSource.Services; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Part = PartSource.Data.Models.Part; namespace PartSource.Api.Controllers { [Route("v2/[controller]")] [ApiController] [ApiExplorerSettings(GroupName = "v1")] public class PartsController : BaseNexpartController { private readonly NexpartService _nexpartService; private readonly PartService _partService; private readonly VehicleService _vehicleService; private readonly FitmentService _fitmentService; public PartsController(NexpartService nexpartService, PartService partService, VehicleService vehicleService, FitmentService fitmentService) { _nexpartService = nexpartService; _partService = partService; _vehicleService = vehicleService; _fitmentService = fitmentService; } [HttpGet] [Route("fitment")] [Route("fitmentnote")] public async Task GetFitment([FromQuery] string sku, [FromQuery] int vehicleId) { VehicleFitmentDto vehicleFitment = await _fitmentService.GetFitmentNotes(sku, vehicleId); if (vehicleFitment == null) { return NotFound(); } try { string[] segments = vehicleFitment.NoteText.Split(']'); vehicleFitment.PartDescription = segments[0].TrimStart('['); vehicleFitment.DriveTypes = GetDriveTypesFromNote(vehicleFitment.NoteText); vehicleFitment.Notes = segments[1].Split(';') .Select(n => n.Trim()) .ToList(); } catch { throw new InvalidOperationException($"The note_text field provided by WHI for {vehicleFitment.LineCode} {vehicleFitment.PartNumber} was in an invalid format."); } SmartPageDataSearch smartPageDataSearch = new SmartPageDataSearch { Items = new[] { new Item { PartNumber = vehicleFitment.PartNumber, MfrCode = vehicleFitment.LineCode } } }; SmartPageDataSearchResponse smartPageResponse = await _nexpartService.SendRequest(smartPageDataSearch); if (smartPageResponse.ResponseBody?.Item != null) { PartType[] partTypes = smartPageResponse.ResponseBody.Item.Select(i => new PartType { Id = i.Part.PartType.Id }) .ToArray(); ApplicationSearch applicationSearch = new ApplicationSearch { VehicleIdentifier = new VehicleIdentifier { BaseVehicleId = vehicleFitment.BaseVehicleId, EngineConfigId = vehicleFitment.EngineConfigId }, MfrCode = new[] { vehicleFitment.LineCode }, PartType = partTypes, GroupBy = "MFR", QuestionOption = "QUESTION_OTHERWISE_APP" }; ApplicationSearchResponse response = await _nexpartService.SendRequest(applicationSearch); if (response.ResponseBody != null && response.ResponseBody is Questions) { Question driveTypeQuestion = ((Questions)response.ResponseBody).Question .Where(q => q.Attribute == "DRIVE_TYPE") .FirstOrDefault(); if (driveTypeQuestion != null) { foreach (Answer answer in driveTypeQuestion.Answer) { applicationSearch.Criterion = new[] { new Criterion { Attribute = "DRIVE_TYPE", Id = answer.Id} }; ApplicationSearchResponse driveTypeResponse = await _nexpartService.SendRequest(applicationSearch); if (driveTypeResponse.ResponseBody != null && ((Apps)driveTypeResponse.ResponseBody).App.Where(a => a.Part == vehicleFitment.PartNumber).Any()) { vehicleFitment.DriveTypes.Add(answer.Value); } } } } } return Ok(vehicleFitment); } [HttpGet] [Route("positions")] public async Task GetPositions([FromQuery] string sku, [FromQuery] int vehicleId) { Part part = await _partService.GetPartBySku(sku); Vehicle vehicle = await _vehicleService.GetVehicleById(vehicleId); if (part == null) { return BadRequest(new { Message = $"No part data is available for SKU {sku}. Confirm it is available in the database maintained by Sound Press.", Reason = $"{nameof(_partService.GetPartBySku)} returned null" }); } if (vehicle == null) { return BadRequest(new { Message = $"No vehicle data is available for vehicle ID {vehicleId}. Confirm it is available in the database maintained by Sound Press.", Reason = $"{nameof(_vehicleService.GetVehicleById)} returned null" }); } IList mappings = await _partService.GetDcfMapping(part.LineCode); Item[] items = mappings.Select(m => new Item { PartNumber = part.PartNumber, MfrCode = m.WhiCode }) .ToArray(); SmartPageDataSearch smartPageDataSearch = new SmartPageDataSearch { Items = items }; SmartPageDataSearchResponse smartPageResponse = await _nexpartService.SendRequest(smartPageDataSearch); if (smartPageResponse.ResponseBody?.Item == null) { return NotFound(new { Message = $"No WHI data is available for SKU {sku}", Reason = $"{nameof(SmartPageDataSearch)} returned null" }); } PartType[] partTypes = smartPageResponse.ResponseBody.Item.Select(i => new PartType { Id = i.Part.PartType.Id }) .ToArray(); ApplicationSearch applicationSearch = new ApplicationSearch { VehicleIdentifier = new VehicleIdentifier { BaseVehicleId = vehicle.BaseVehicleId }, MfrCode = mappings.Select(m => m.WhiCode).ToArray(), PartType = new[] { new PartType { Id = smartPageResponse.ResponseBody.Item[0].Part.PartType.Id } }, Criterion = new[] { new Criterion { Attribute = "REGION", Id = 2 } }, GroupBy = "PARTTYPE" }; ApplicationSearchResponse response = await _nexpartService.SendRequest(applicationSearch); if (response.ResponseBody == null) { return NotFound(new { Message = $"No WHI data is available for SKU {sku}", Reason = $"{nameof(ApplicationSearch)} returned null" }); } IList positions = new List(); foreach (App app in ((Apps)response.ResponseBody)?.App) { if (!string.IsNullOrEmpty(app.Position) && app.Part == part.PartNumber) { positions.Add(app.Position); } } return Ok(new { VehicleId = vehicleId, Sku = sku, Positions = positions.Distinct() }); } private IList GetDriveTypesFromNote(string fitmentNote) { fitmentNote = fitmentNote.ToUpperInvariant(); IList driveTypes = new List(); if (fitmentNote.Contains("FWD")) { driveTypes.Add("FWD"); } if (fitmentNote.Contains("RWD")) { driveTypes.Add("RWD"); } if (fitmentNote.Contains("AWD")) { driveTypes.Add("AWD"); } if (fitmentNote.Contains("4WD")) { driveTypes.Add("4WD"); } return driveTypes; } } }