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.
replaysMike committed May 11, 2023
1 parent 243c915 commit 37d630b
Showing 4 changed files with 145 additions and 134 deletions.
Original file line number Diff line number Diff line change
@@ -450,7 +450,8 @@
"barcodeScanner": "Barcode Scanner",
"printing": "Printing",
"labelTemplates": "Label Templates",
"bulkPrint": "Bulk Print"
"bulkPrint": "Bulk Print",
"inventory": "Inventory"
},
"comp": {
"navBar": {
2 changes: 1 addition & 1 deletion Binner/Binner.Web/ClientApp/src/common/Types.js
Original file line number Diff line number Diff line change
@@ -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];
}
262 changes: 132 additions & 130 deletions Binner/Binner.Web/ClientApp/src/pages/Inventory.js
Original file line number Diff line number Diff line change
@@ -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();
@@ -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;

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

/**
* Do a part information search
@@ -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);
};
12 changes: 10 additions & 2 deletions Binner/Library/Binner.Common/Services/PartService.cs
Original file line number Diff line number Diff line change
@@ -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();

0 comments on commit 37d630b

Please sign in to comment.