mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-12-22 02:49:31 +00:00
Merge branch 'master' into settings-bundle
This commit is contained in:
commit
8750573724
191 changed files with 27745 additions and 12133 deletions
|
|
@ -27,6 +27,7 @@ use App\Entity\Attachments\AttachmentType;
|
|||
use App\Entity\Attachments\PartAttachment;
|
||||
use App\Entity\Base\AbstractStructuralDBElement;
|
||||
use App\Entity\Parameters\PartParameter;
|
||||
use App\Entity\Parts\Category;
|
||||
use App\Entity\Parts\Footprint;
|
||||
use App\Entity\Parts\InfoProviderReference;
|
||||
use App\Entity\Parts\Manufacturer;
|
||||
|
|
@ -36,6 +37,7 @@ use App\Entity\Parts\Supplier;
|
|||
use App\Entity\PriceInformations\Currency;
|
||||
use App\Entity\PriceInformations\Orderdetail;
|
||||
use App\Entity\PriceInformations\Pricedetail;
|
||||
use App\Repository\Parts\CategoryRepository;
|
||||
use App\Services\InfoProviderSystem\DTOs\FileDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||
|
|
@ -160,6 +162,12 @@ final class DTOtoEntityConverter
|
|||
|
||||
$entity->setMass($dto->mass);
|
||||
|
||||
//Try to map the category to an existing entity (but never create a new one)
|
||||
if ($dto->category) {
|
||||
//@phpstan-ignore-next-line For some reason php does not recognize the repo returns a category
|
||||
$entity->setCategory($this->em->getRepository(Category::class)->findForInfoProvider($dto->category));
|
||||
}
|
||||
|
||||
$entity->setManufacturer($this->getOrCreateEntity(Manufacturer::class, $dto->manufacturer));
|
||||
$entity->setFootprint($this->getOrCreateEntity(Footprint::class, $dto->footprint));
|
||||
|
||||
|
|
|
|||
77
src/Services/InfoProviderSystem/ExistingPartFinder.php
Normal file
77
src/Services/InfoProviderSystem/ExistingPartFinder.php
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\InfoProviderSystem;
|
||||
|
||||
use App\Entity\Parts\Manufacturer;
|
||||
use App\Entity\Parts\Part;
|
||||
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
* This service assists in finding existing local parts for a SearchResultDTO, so that the user
|
||||
* does not accidentally add a duplicate.
|
||||
*
|
||||
* A part is considered to be a duplicate, if the provider reference matches, or if the manufacturer and the MPN of the
|
||||
* DTO and the local part match. This checks also for alternative names of the manufacturer and the part name (as alternative
|
||||
* for the MPN).
|
||||
*/
|
||||
final class ExistingPartFinder
|
||||
{
|
||||
public function __construct(private readonly EntityManagerInterface $em)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first existing local part, that matches the search result.
|
||||
* If no part is found, return null.
|
||||
* @param SearchResultDTO $dto
|
||||
* @return Part|null
|
||||
*/
|
||||
public function findFirstExisting(SearchResultDTO $dto): ?Part
|
||||
{
|
||||
$results = $this->findAllExisting($dto);
|
||||
return count($results) > 0 ? $results[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all existing local parts that match the search result.
|
||||
* If no part is found, return an empty array.
|
||||
* @param SearchResultDTO $dto
|
||||
* @return Part[]
|
||||
*/
|
||||
public function findAllExisting(SearchResultDTO $dto): array
|
||||
{
|
||||
$qb = $this->em->getRepository(Part::class)->createQueryBuilder('part');
|
||||
$qb->select('part')
|
||||
->leftJoin('part.manufacturer', 'manufacturer')
|
||||
->Orwhere($qb->expr()->andX(
|
||||
'part.providerReference.provider_key = :providerKey',
|
||||
'part.providerReference.provider_id = :providerId',
|
||||
))
|
||||
|
||||
//Or the manufacturer (allowing for alternative names) and the MPN (or part name) must match
|
||||
->OrWhere(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->orX(
|
||||
"ILIKE(manufacturer.name, :manufacturerName) = TRUE",
|
||||
"ILIKE(manufacturer.alternative_names, :manufacturerAltNames) = TRUE",
|
||||
),
|
||||
$qb->expr()->orX(
|
||||
"ILIKE(part.manufacturer_product_number, :mpn) = TRUE",
|
||||
"ILIKE(part.name, :mpn) = TRUE",
|
||||
)
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
$qb->setParameter('providerKey', $dto->provider_key);
|
||||
$qb->setParameter('providerId', $dto->provider_id);
|
||||
|
||||
$qb->setParameter('manufacturerName', $dto->manufacturer);
|
||||
$qb->setParameter('manufacturerAltNames', '%'.$dto->manufacturer.'%');
|
||||
$qb->setParameter('mpn', $dto->mpn);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,14 @@ class DigikeyProvider implements InfoProviderInterface
|
|||
|
||||
private readonly HttpClientInterface $digikeyClient;
|
||||
|
||||
/**
|
||||
* A list of parameter IDs, that are always assumed as text only and will never be converted to a numerical value.
|
||||
* This allows to fix issues like #682, where the "Supplier Device Package" was parsed as a numerical value.
|
||||
*/
|
||||
private const TEXT_ONLY_PARAMETERS = [
|
||||
1291, //Supplier Device Package
|
||||
39246, //Package / Case
|
||||
];
|
||||
|
||||
public function __construct(HttpClientInterface $httpClient, private readonly OAuthTokenManager $authTokenManager,
|
||||
private readonly string $currency, private readonly string $clientId,
|
||||
|
|
@ -214,7 +222,12 @@ class DigikeyProvider implements InfoProviderInterface
|
|||
continue;
|
||||
}
|
||||
|
||||
$results[] = ParameterDTO::parseValueIncludingUnit($parameter['Parameter'], $parameter['Value']);
|
||||
//If the parameter was marked as text only, then we do not try to parse it as a numerical value
|
||||
if (in_array($parameter['ParameterId'], self::TEXT_ONLY_PARAMETERS, true)) {
|
||||
$results[] = new ParameterDTO(name: $parameter['Parameter'], value_text: $parameter['Value']);
|
||||
} else { //Otherwise try to parse it as a numerical value
|
||||
$results[] = ParameterDTO::parseValueIncludingUnit($parameter['Parameter'], $parameter['Value']);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
|
|
|
|||
|
|
@ -98,16 +98,19 @@ class LCSCProvider implements InfoProviderInterface
|
|||
private function getRealDatasheetUrl(?string $url): string
|
||||
{
|
||||
if ($url !== null && trim($url) !== '' && preg_match("/^https:\/\/(datasheet\.lcsc\.com|www\.lcsc\.com\/datasheet)\/.*(C\d+)\.pdf$/", $url, $matches) > 0) {
|
||||
if (preg_match("/^https:\/\/datasheet\.lcsc\.com\/lcsc\/(.*\.pdf)$/", $url, $rewriteMatches) > 0) {
|
||||
$url = 'https://www.lcsc.com/datasheet/lcsc_datasheet_' . $rewriteMatches[1];
|
||||
}
|
||||
$response = $this->lcscClient->request('GET', $url, [
|
||||
'headers' => [
|
||||
'Referer' => 'https://www.lcsc.com/product-detail/_' . $matches[2] . '.html'
|
||||
],
|
||||
]);
|
||||
if (preg_match('/(pdfUrl): ?("[^"]+wmsc\.lcsc\.com[^"]+\.pdf")/', $response->getContent(), $matches) > 0) {
|
||||
if (preg_match('/(previewPdfUrl): ?("[^"]+wmsc\.lcsc\.com[^"]+\.pdf")/', $response->getContent(), $matches) > 0) {
|
||||
//HACKY: The URL string contains escaped characters like \u002F, etc. To decode it, the JSON decoding is reused
|
||||
//See https://github.com/Part-DB/Part-DB-server/pull/582#issuecomment-2033125934
|
||||
$jsonObj = json_decode('{"' . $matches[1] . '": ' . $matches[2] . '}');
|
||||
$url = $jsonObj->pdfUrl;
|
||||
$url = $jsonObj->previewPdfUrl;
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ class MouserProvider implements InfoProviderInterface
|
|||
if (isset($arr['SearchResults'])) {
|
||||
$products = $arr['SearchResults']['Parts'] ?? [];
|
||||
} else {
|
||||
throw new \RuntimeException('Unknown response format');
|
||||
throw new \RuntimeException('Unknown response format: ' .json_encode($arr, JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
|
|
|||
1471
src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php
Normal file
1471
src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue