Skip to content

Commit

Permalink
Fixes #191 - a part was discovered that DigiKey returns multiple moun…
Browse files Browse the repository at this point in the history
…ting types for ??, so needed to handle the edge case.

Also, another memoization issue found when barcode scanning part quantities losing the correct value due to multiple api lookups. A better fix needs to be followed up with at a later time.
  • Loading branch information
replaysMike committed May 11, 2023
1 parent 243c915 commit 37d630b
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,8 @@
"barcodeScanner": "Barcode Scanner",
"printing": "Printing",
"labelTemplates": "Label Templates",
"bulkPrint": "Bulk Print"
"bulkPrint": "Bulk Print",
"inventory": "Inventory"
},
"comp": {
"navBar": {
Expand Down
2 changes: 1 addition & 1 deletion Binner/Binner.Web/ClientApp/src/common/Types.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const BooleanTypes = {
switch(typeof valueType){
case "object":
const matchingType = _.findWhere(typeValues, { value: value });
return matchingType.name;
return matchingType?.name;
default:
return typeKeys[value];
}
Expand Down
262 changes: 132 additions & 130 deletions Binner/Binner.Web/ClientApp/src/pages/Inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ export function Inventory(props) {
const mountingTypeOptions = GetAdvancedTypeDropdown(MountingTypes, true);

// todo: find a better alternative, we shouldn't need to do this!
const partRef = useRef();
partRef.current = part;
const bulkScanIsOpenRef = useRef();
bulkScanIsOpenRef.current = bulkScanIsOpen;
const partTypesRef = useRef();
Expand Down Expand Up @@ -183,7 +185,135 @@ export function Inventory(props) {
}
};

const processPartMetadataResponse = (data, localPart) => {
const setPartFromMetadata = useCallback((metadataParts, suggestedPart) => {
if (partTypesRef.current.length === 0)
console.error("There are no partTypes! This shouldn't happen and is a bug.");

const entity = { ...partRef.current };
const mappedPart = {
partNumber: suggestedPart.basePartNumber,
partTypeId: getPartTypeId(suggestedPart.partType, partTypesRef.current),
mountingTypeId: suggestedPart.mountingTypeId,
packageType: suggestedPart.packageType,
keywords: suggestedPart.keywords && suggestedPart.keywords.join(" ").toLowerCase(),
description: suggestedPart.description,
datasheetUrls: suggestedPart.datasheetUrls,
supplier: suggestedPart.supplier,
supplierPartNumber: suggestedPart.supplierPartNumber,
cost: suggestedPart.cost,
productUrl: suggestedPart.productUrl,
manufacturer: suggestedPart.manufacturer,
manufacturerPartNumber: suggestedPart.manufacturerPartNumber,
imageUrl: suggestedPart.imageUrl,
status: suggestedPart.status,
quantity: suggestedPart.quantity,
};

if (mappedPart.quantity > 0)
entity.quantity = mappedPart.quantity;

entity.partNumber = mappedPart.partNumber;
entity.supplier = mappedPart.supplier;
entity.supplierPartNumber = mappedPart.supplierPartNumber;
if (mappedPart.partTypeId) entity.partTypeId = mappedPart.partTypeId || "";
if (mappedPart.mountingTypeId) entity.mountingTypeId = mappedPart.mountingTypeId || "";
entity.packageType = mappedPart.packageType || "";
entity.cost = mappedPart.cost || 0.0;
entity.keywords = mappedPart.keywords || "";
entity.description = mappedPart.description || "";
entity.manufacturer = mappedPart.manufacturer || "";
entity.manufacturerPartNumber = mappedPart.manufacturerPartNumber || "";
entity.productUrl = mappedPart.productUrl || "";
entity.imageUrl = mappedPart.imageUrl || "";
if (mappedPart.datasheetUrls.length > 0) {
entity.datasheetUrl = _.first(mappedPart.datasheetUrls) || "";
}
if (mappedPart.supplier === "DigiKey") {
entity.digiKeyPartNumber = mappedPart.supplierPartNumber || "";
// also map mouser
let searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Mouser" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.mouserPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map arrow
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Arrow" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.arrowPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}

}
if (mappedPart.supplier === "Mouser") {
entity.mouserPartNumber = mappedPart.supplierPartNumber || "";
// also map digikey
let searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "DigiKey" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.digiKeyPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map arrow
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Arrow" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.arrowPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}
if (mappedPart.supplier === "Arrow") {
entity.arrowPartNumber = mappedPart.supplierPartNumber || "";
// also map digikey
let searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "DigiKey" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.digiKeyPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map mouser
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Mouser" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.mouserPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}

const lowestCostPart = _.first(
_.sortBy(
_.filter(metadataParts, (i) => i.cost > 0),
"cost"
)
);

if (lowestCostPart) {
entity.lowestCostSupplier = lowestCostPart.supplier;
entity.lowestCostSupplierUrl = lowestCostPart.productUrl;
}
setPart(entity);
}, [part]);

const processPartMetadataResponse = useCallback((data, localPart) => {
// cancelled or auth required
if (!data) return;

Expand Down Expand Up @@ -214,7 +344,7 @@ export function Inventory(props) {
setInfoResponse(infoResponse);
setMetadataParts(metadataParts);
setLoadingPartMetadata(false);
};
}, [part, pageHasParameters, setPartFromMetadata]);

/**
* Do a part information search
Expand Down Expand Up @@ -709,134 +839,6 @@ export function Inventory(props) {
await fetchApi(`api/part/print?partNumber=${part.partNumber.trim()}&generateImageOnly=false`, { method: "POST" });
};

const setPartFromMetadata = (metadataParts, suggestedPart) => {
if (partTypesRef.current.length === 0)
console.error("There are no partTypes! This shouldn't happen and is a bug.");

const entity = { ...part };
const mappedPart = {
partNumber: suggestedPart.basePartNumber,
partTypeId: getPartTypeId(suggestedPart.partType, partTypesRef.current),
mountingTypeId: suggestedPart.mountingTypeId,
packageType: suggestedPart.packageType,
keywords: suggestedPart.keywords && suggestedPart.keywords.join(" ").toLowerCase(),
description: suggestedPart.description,
datasheetUrls: suggestedPart.datasheetUrls,
supplier: suggestedPart.supplier,
supplierPartNumber: suggestedPart.supplierPartNumber,
cost: suggestedPart.cost,
productUrl: suggestedPart.productUrl,
manufacturer: suggestedPart.manufacturer,
manufacturerPartNumber: suggestedPart.manufacturerPartNumber,
imageUrl: suggestedPart.imageUrl,
status: suggestedPart.status,
quantity: suggestedPart.quantity,
};

if (mappedPart.quantity > 0)
entity.quantity = mappedPart.quantity;

entity.partNumber = mappedPart.partNumber;
entity.supplier = mappedPart.supplier;
entity.supplierPartNumber = mappedPart.supplierPartNumber;
if (mappedPart.partTypeId) entity.partTypeId = mappedPart.partTypeId || "";
if (mappedPart.mountingTypeId) entity.mountingTypeId = mappedPart.mountingTypeId || "";
entity.packageType = mappedPart.packageType || "";
entity.cost = mappedPart.cost || 0.0;
entity.keywords = mappedPart.keywords || "";
entity.description = mappedPart.description || "";
entity.manufacturer = mappedPart.manufacturer || "";
entity.manufacturerPartNumber = mappedPart.manufacturerPartNumber || "";
entity.productUrl = mappedPart.productUrl || "";
entity.imageUrl = mappedPart.imageUrl || "";
if (mappedPart.datasheetUrls.length > 0) {
entity.datasheetUrl = _.first(mappedPart.datasheetUrls) || "";
}
if (mappedPart.supplier === "DigiKey") {
entity.digiKeyPartNumber = mappedPart.supplierPartNumber || "";
// also map mouser
let searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Mouser" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.mouserPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map arrow
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Arrow" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.arrowPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}

}
if (mappedPart.supplier === "Mouser") {
entity.mouserPartNumber = mappedPart.supplierPartNumber || "";
// also map digikey
let searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "DigiKey" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.digiKeyPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map arrow
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Arrow" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.arrowPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}
if (mappedPart.supplier === "Arrow") {
entity.arrowPartNumber = mappedPart.supplierPartNumber || "";
// also map digikey
let searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "DigiKey" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.digiKeyPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
// also map mouser
searchResult = _.find(metadataParts, (e) => {
return e !== undefined && e.supplier === "Mouser" && e.manufacturerPartNumber === mappedPart.manufacturerPartNumber;
});
if (searchResult) {
entity.mouserPartNumber = searchResult.supplierPartNumber;
if (entity.packageType.length === 0) entity.packageType = searchResult.packageType;
if (entity.datasheetUrl.length === 0) entity.datasheetUrl = _.first(searchResult.datasheetUrls) || "";
if (entity.imageUrl.length === 0) entity.imageUrl = searchResult.imageUrl;
}
}

const lowestCostPart = _.first(
_.sortBy(
_.filter(metadataParts, (i) => i.cost > 0),
"cost"
)
);

if (lowestCostPart) {
entity.lowestCostSupplier = lowestCostPart.supplier;
entity.lowestCostSupplierUrl = lowestCostPart.productUrl;
}
setPart(entity);
};

const handleChooseAlternatePart = (e, part) => {
setPartFromMetadata(metadataParts, part);
};
Expand Down
12 changes: 10 additions & 2 deletions Binner/Library/Binner.Common/Services/PartService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,10 +1136,18 @@ Task ProcessDigikeyResponseAsync(string partNumber, PartResults response, Keywor
if (string.IsNullOrEmpty(basePart))
basePart = part.ManufacturerPartNumber;
var mountingTypeId = MountingType.None;
Enum.TryParse<MountingType>(part.Parameters
var mountingTypeParameter = part.Parameters
.Where(x => x.Parameter.Equals("Mounting Type", ComparisonType))
.Select(x => x.Value?.Replace(" ", ""))
.FirstOrDefault(), out mountingTypeId);
.FirstOrDefault();

if (mountingTypeParameter?.Contains(",") == true)
{
// DigiKey very rarely returns a part as being more than one mounting type. Pick the last one.
mountingTypeParameter = mountingTypeParameter.Split(",", StringSplitOptions.RemoveEmptyEntries).Last();
}

Enum.TryParse<MountingType>(mountingTypeParameter, out mountingTypeId);
var currency = digikeyResponse.SearchLocaleUsed.Currency;
if (string.IsNullOrEmpty(currency))
currency = _configuration.Locale.Currency.ToString().ToUpper();
Expand Down

0 comments on commit 37d630b

Please sign in to comment.