Daniel 1 рік тому
джерело
коміт
c6766fd28c
23 змінених файлів з 1640 додано та 23 видалено
  1. +1
    -0
      .env
  2. +1
    -0
      .gitignore
  3. +1
    -0
      composer.json
  4. +504
    -1
      composer.lock
  5. +1
    -1
      export/openapi.json
  6. +270
    -0
      export/openapi.yaml
  7. +33
    -0
      migrations/Version20240625160530.php
  8. +31
    -0
      migrations/Version20240626132451.php
  9. +31
    -0
      migrations/Version20240626134457.php
  10. +31
    -0
      migrations/Version20240626142052.php
  11. +24
    -2
      src/ApiResource/PartnerApi.php
  12. +22
    -0
      src/ApiResource/ProductApi.php
  13. +47
    -0
      src/Command/ImportNavisionDataCommand.php
  14. +10
    -0
      src/DataFixtures/AppFixtures.php
  15. +181
    -6
      src/Entity/Partner.php
  16. +163
    -1
      src/Entity/Product.php
  17. +20
    -1
      src/Factory/PartnerFactory.php
  18. +10
    -0
      src/Factory/ProductFactory.php
  19. +24
    -9
      src/Mapper/PartnerApiToEntityMapper.php
  20. +12
    -0
      src/Mapper/PartnerEntityToApiMapper.php
  21. +15
    -2
      src/Mapper/ProductApiToEntityMapper.php
  22. +10
    -0
      src/Mapper/ProductEntityToApiMapper.php
  23. +198
    -0
      src/Service/NavisionDataImportService.php

+ 1
- 0
.env Переглянути файл

@@ -48,3 +48,4 @@ JWT_PASSPHRASE=dd92770a0c99773cc99cf1bdc4bd425986dacbcde1bc753e9934614aa6f364b6
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###
ADMIN_EMAIL=re@spawntree.de

+ 1
- 0
.gitignore Переглянути файл

@@ -4,6 +4,7 @@
/.env.local.php
/.env.*.local
/config/secrets/prod/prod.decrypt.private.php
/import/
/public/bundles/
/public/media/
/public/document/


+ 1
- 0
composer.json Переглянути файл

@@ -14,6 +14,7 @@
"lexik/jwt-authentication-bundle": "^2.20",
"nelmio/cors-bundle": "^2.4",
"phpdocumentor/reflection-docblock": "^5.3",
"phpoffice/phpspreadsheet": "^2.1",
"phpstan/phpdoc-parser": "^1.24",
"symfony/asset": "7.0.*",
"symfony/console": "7.0.*",


+ 504
- 1
composer.lock Переглянути файл

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "c9bac256c39d8d375145ec076da8a3cc",
"content-hash": "5fdfe7c840f4a9d98a61fc69063f7142",
"packages": [
{
"name": "api-platform/core",
@@ -1881,6 +1881,194 @@
],
"time": "2023-12-14T15:58:11+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/b8174494eda667f7d13876b4a7bfef0f62a7c0d1",
"reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-zlib": "*",
"php-64bit": "^8.1"
},
"require-dev": {
"ext-zip": "*",
"friendsofphp/php-cs-fixer": "^3.16",
"guzzlehttp/guzzle": "^7.5",
"mikey179/vfsstream": "^1.6",
"php-coveralls/php-coveralls": "^2.5",
"phpunit/phpunit": "^10.0",
"vimeo/psalm": "^5.0"
},
"suggest": {
"guzzlehttp/psr7": "^2.4",
"psr/http-message": "^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "András Kolesár",
"email": "kolesar@kolesar.hu"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"support": {
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.0"
},
"funding": [
{
"url": "https://github.com/maennchen",
"type": "github"
},
{
"url": "https://opencollective.com/zipstream",
"type": "open_collective"
}
],
"time": "2023-06-21T14:59:35+00:00"
},
{
"name": "markbaker/complex",
"version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
},
"time": "2022-12-06T16:21:08+00:00"
},
{
"name": "markbaker/matrix",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@demon-angel.eu"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
},
"time": "2022-12-02T22:17:43+00:00"
},
{
"name": "monolog/monolog",
"version": "3.5.0",
@@ -2279,6 +2467,110 @@
},
"time": "2024-02-23T11:10:43+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "dbed77bd3a0f68f96c0dd68ad4499d5674fecc3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/dbed77bd3a0f68f96c0dd68ad4499d5674fecc3e",
"reference": "dbed77bd3a0f68f96c0dd68ad4499d5674fecc3e",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"maennchen/zipstream-php": "^2.1 || ^3.0",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^8.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
"dompdf/dompdf": "^2.0",
"friendsofphp/php-cs-fixer": "^3.2",
"mitoteam/jpgraph": "^10.3",
"mpdf/mpdf": "^8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^9.6",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.5"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"ext-intl": "PHP Internationalization Functions",
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
},
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/2.1.0"
},
"time": "2024-05-11T04:17:56+00:00"
},
{
"name": "phpstan/phpdoc-parser",
"version": "1.26.0",
@@ -2526,6 +2818,166 @@
},
"time": "2019-01-08T18:20:26+00:00"
},
{
"name": "psr/http-client",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-client.git",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP clients",
"homepage": "https://github.com/php-fig/http-client",
"keywords": [
"http",
"http-client",
"psr",
"psr-18"
],
"support": {
"source": "https://github.com/php-fig/http-client"
},
"time": "2023-09-23T14:17:50+00:00"
},
{
"name": "psr/http-factory",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-factory.git",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"shasum": ""
},
"require": {
"php": ">=7.1",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-factory"
},
"time": "2024-04-15T12:06:14+00:00"
},
{
"name": "psr/http-message",
"version": "2.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/2.0"
},
"time": "2023-04-04T09:54:51+00:00"
},
{
"name": "psr/link",
"version": "2.0.1",
@@ -2632,6 +3084,57 @@
},
"time": "2021-07-14T16:46:02+00:00"
},
{
"name": "psr/simple-cache",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/simple-cache.git",
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865",
"reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\SimpleCache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interfaces for simple caching",
"keywords": [
"cache",
"caching",
"psr",
"psr-16",
"simple-cache"
],
"support": {
"source": "https://github.com/php-fig/simple-cache/tree/3.0.0"
},
"time": "2021-10-29T13:26:27+00:00"
},
{
"name": "symfony/asset",
"version": "v7.0.3",


+ 1
- 1
export/openapi.json
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 270
- 0
export/openapi.yaml Переглянути файл

@@ -5376,6 +5376,14 @@ components:
properties:
name:
type: string
navisionId:
type:
- integer
- 'null'
nameAddition:
type:
- string
- 'null'
partnerType:
type: string
enum:
@@ -5390,6 +5398,10 @@ components:
type:
- string
- 'null'
addressAddition:
type:
- string
- 'null'
streetNo:
type:
- string
@@ -5406,6 +5418,42 @@ components:
type:
- string
- 'null'
phone:
type:
- string
- 'null'
language:
type:
- string
- 'null'
currency:
type:
- string
- 'null'
paymentCondition:
type:
- string
- 'null'
deliveryCondition:
type:
- string
- 'null'
businessGroup:
type:
- string
- 'null'
vatBusinessGroup:
type:
- string
- 'null'
creditLimit:
type:
- integer
- 'null'
routePoint:
type:
- string
- 'null'
website:
type:
- string
@@ -5453,6 +5501,14 @@ components:
format: iri-reference
name:
type: string
navisionId:
type:
- integer
- 'null'
nameAddition:
type:
- string
- 'null'
partnerType:
type: string
enum:
@@ -5467,6 +5523,10 @@ components:
type:
- string
- 'null'
addressAddition:
type:
- string
- 'null'
streetNo:
type:
- string
@@ -5483,6 +5543,42 @@ components:
type:
- string
- 'null'
phone:
type:
- string
- 'null'
language:
type:
- string
- 'null'
currency:
type:
- string
- 'null'
paymentCondition:
type:
- string
- 'null'
deliveryCondition:
type:
- string
- 'null'
businessGroup:
type:
- string
- 'null'
vatBusinessGroup:
type:
- string
- 'null'
creditLimit:
type:
- integer
- 'null'
routePoint:
type:
- string
- 'null'
website:
type:
- string
@@ -5544,6 +5640,14 @@ components:
type: string
name:
type: string
navisionId:
type:
- integer
- 'null'
nameAddition:
type:
- string
- 'null'
partnerType:
type: string
enum:
@@ -5558,6 +5662,10 @@ components:
type:
- string
- 'null'
addressAddition:
type:
- string
- 'null'
streetNo:
type:
- string
@@ -5574,6 +5682,42 @@ components:
type:
- string
- 'null'
phone:
type:
- string
- 'null'
language:
type:
- string
- 'null'
currency:
type:
- string
- 'null'
paymentCondition:
type:
- string
- 'null'
deliveryCondition:
type:
- string
- 'null'
businessGroup:
type:
- string
- 'null'
vatBusinessGroup:
type:
- string
- 'null'
creditLimit:
type:
- integer
- 'null'
routePoint:
type:
- string
- 'null'
website:
type:
- string
@@ -6272,6 +6416,8 @@ components:
deprecated: false
required:
- name
- blocked
- inventory
properties:
name:
type: string
@@ -6279,6 +6425,46 @@ components:
type:
- string
- 'null'
blocked:
type:
- boolean
- 'null'
inventory:
type:
- number
- 'null'
baseUnit:
type:
- string
- 'null'
buyUnit:
type:
- string
- 'null'
sellUnit:
type:
- string
- 'null'
trackingCode:
type:
- string
- 'null'
productGroup:
type:
- string
- 'null'
customsPosition:
type:
- string
- 'null'
productBookingGroup:
type:
- string
- 'null'
vatProductBookingGroup:
type:
- string
- 'null'
image:
type:
- string
@@ -6305,6 +6491,8 @@ components:
deprecated: false
required:
- name
- blocked
- inventory
properties:
_links:
type: object
@@ -6321,6 +6509,46 @@ components:
type:
- string
- 'null'
blocked:
type:
- boolean
- 'null'
inventory:
type:
- number
- 'null'
baseUnit:
type:
- string
- 'null'
buyUnit:
type:
- string
- 'null'
sellUnit:
type:
- string
- 'null'
trackingCode:
type:
- string
- 'null'
productGroup:
type:
- string
- 'null'
customsPosition:
type:
- string
- 'null'
productBookingGroup:
type:
- string
- 'null'
vatProductBookingGroup:
type:
- string
- 'null'
image:
type:
- string
@@ -6347,6 +6575,8 @@ components:
deprecated: false
required:
- name
- blocked
- inventory
properties:
'@context':
readOnly: true
@@ -6377,6 +6607,46 @@ components:
type:
- string
- 'null'
blocked:
type:
- boolean
- 'null'
inventory:
type:
- number
- 'null'
baseUnit:
type:
- string
- 'null'
buyUnit:
type:
- string
- 'null'
sellUnit:
type:
- string
- 'null'
trackingCode:
type:
- string
- 'null'
productGroup:
type:
- string
- 'null'
customsPosition:
type:
- string
- 'null'
productBookingGroup:
type:
- string
- 'null'
vatProductBookingGroup:
type:
- string
- 'null'
image:
type:
- string


+ 33
- 0
migrations/Version20240625160530.php Переглянути файл

@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240625160530 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE partner ADD name_addition VARCHAR(255) DEFAULT NULL, ADD address_addition VARCHAR(255) DEFAULT NULL, ADD phone VARCHAR(255) DEFAULT NULL, ADD language VARCHAR(255) DEFAULT NULL, ADD currency VARCHAR(255) DEFAULT NULL, ADD payment_condition VARCHAR(255) DEFAULT NULL, ADD delivery_condition VARCHAR(255) DEFAULT NULL, ADD business_group VARCHAR(255) DEFAULT NULL, ADD vat_business_group VARCHAR(255) DEFAULT NULL, ADD credit_limit INT DEFAULT NULL, ADD route_point VARCHAR(255) DEFAULT NULL');
$this->addSql('ALTER TABLE product ADD description_addition VARCHAR(255) DEFAULT NULL, ADD blocked TINYINT(1) NOT NULL, ADD inventory DOUBLE PRECISION NOT NULL, ADD base_unit VARCHAR(255) DEFAULT NULL, ADD buy_unit VARCHAR(255) DEFAULT NULL, ADD sell_unit VARCHAR(255) DEFAULT NULL, ADD tracking_code VARCHAR(255) DEFAULT NULL, ADD product_group VARCHAR(255) DEFAULT NULL, ADD customs_position VARCHAR(255) DEFAULT NULL, ADD product_booking_group VARCHAR(255) DEFAULT NULL, ADD vat_product_booking_group VARCHAR(255) DEFAULT NULL');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE product DROP description_addition, DROP blocked, DROP inventory, DROP base_unit, DROP buy_unit, DROP sell_unit, DROP tracking_code, DROP product_group, DROP customs_position, DROP product_booking_group, DROP vat_product_booking_group');
$this->addSql('ALTER TABLE partner DROP name_addition, DROP address_addition, DROP phone, DROP language, DROP currency, DROP payment_condition, DROP delivery_condition, DROP business_group, DROP vat_business_group, DROP credit_limit, DROP route_point');
}
}

+ 31
- 0
migrations/Version20240626132451.php Переглянути файл

@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240626132451 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE UNIQUE INDEX UNIQ_312B3E165E237E06 ON partner (name)');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP INDEX UNIQ_312B3E165E237E06 ON partner');
}
}

+ 31
- 0
migrations/Version20240626134457.php Переглянути файл

@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240626134457 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('DROP INDEX UNIQ_312B3E165E237E06 ON partner');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE UNIQUE INDEX UNIQ_312B3E165E237E06 ON partner (name)');
}
}

+ 31
- 0
migrations/Version20240626142052.php Переглянути файл

@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240626142052 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE product DROP description_addition');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE product ADD description_addition VARCHAR(255) DEFAULT NULL');
}
}

+ 24
- 2
src/ApiResource/PartnerApi.php Переглянути файл

@@ -20,12 +20,10 @@ use App\Enum\PartnerType;
use App\Filter\PartnerUnassignedFilter;
use App\State\EntityClassDtoStateProcessor;
use App\State\EntityToDtoStateProvider;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Validator\Constraints\NotBlank;

#[ApiResource(
@@ -62,6 +60,10 @@ class PartnerApi
#[NotBlank]
public string $name;

public ?int $navisionId;

public ?string $nameAddition = null;

#[NotBlank]
public PartnerType $partnerType;

@@ -69,6 +71,8 @@ class PartnerApi

public ?string $street = null;

public ?string $addressAddition = null;

public ?string $streetNo = null;

public ?string $zip = null;
@@ -77,6 +81,24 @@ class PartnerApi

public ?string $country = null;

public ?string $phone = null;

public ?string $language = null;

public ?string $currency = null;

public ?string $paymentCondition = null;

public ?string $deliveryCondition = null;

public ?string $businessGroup = null;

public ?string $vatBusinessGroup = null;

public ?int $creditLimit = null;

public ?string $routePoint = null;

public ?string $website = null;

public ?MediaObject $logo = null;


+ 22
- 0
src/ApiResource/ProductApi.php Переглянути файл

@@ -64,6 +64,28 @@ class ProductApi

public ?string $description = null;

#[NotBlank]
public ?bool $blocked = null;

#[NotBlank]
public ?float $inventory = null;

public ?string $baseUnit = null;

public ?string $buyUnit = null;

public ?string $sellUnit = null;

public ?string $trackingCode = null;

public ?string $productGroup = null;

public ?string $customsPosition = null;

public ?string $productBookingGroup = null;

public ?string $vatProductBookingGroup = null;

public ?MediaObject $image = null;

#[ApiProperty(writable: false)]


+ 47
- 0
src/Command/ImportNavisionDataCommand.php Переглянути файл

@@ -0,0 +1,47 @@
<?php

namespace App\Command;
use App\Entity\Account;
use App\Service\FutTransferService;
use App\Service\NavisionDataImportService;
use App\Service\PriceService;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;

#[AsCommand(name: 'app:import-navision-data')]
class ImportNavisionDataCommand extends Command
{

protected OutputInterface $output;

public function __construct(
private NavisionDataImportService $dataImportService
) {
parent::__construct();
}

protected function configure(): void
{
$this
->setDescription('Import navision data.')
;
}

protected function initialize(InputInterface $input, OutputInterface $output): void
{
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->dataImportService->importCustomers();
$this->dataImportService->importSuppliers();
$this->dataImportService->importProducts();


return Command::SUCCESS;
}

}

+ 10
- 0
src/DataFixtures/AppFixtures.php Переглянути файл

@@ -56,6 +56,16 @@ class AppFixtures extends Fixture
}
}

$system = UserFactory::createOne(
[
'email' => 're@spawntree.de',
'firstName' => 'System',
'lastName' => 'System',
'password' => '12spawntree345',
'roles' => ['ROLE_ADMIN']
]
);
$system->save();

$adminD = UserFactory::createOne(
[


+ 181
- 6
src/Entity/Partner.php Переглянути файл

@@ -18,7 +18,7 @@ class Partner
private ?int $id = null;

#[ORM\Column(type: "integer", unique: true, nullable: true, options: ["unsigned" => true])]
protected int $navisionId;
protected ?int $navisionId;

#[ORM\Column(length: 255)]
private string $name;
@@ -51,12 +51,38 @@ class Partner
#[ORM\JoinColumn(nullable: true, onDelete: "SET NULL")]
private ?MediaObject $logo = null;

#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private ?User $createdBy = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $nameAddition = null;

#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $addressAddition = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $phone = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $language = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $currency = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $paymentCondition = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $deliveryCondition = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $businessGroup = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $vatBusinessGroup = null;

#[ORM\Column(nullable: true)]
private ?int $creditLimit = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $routePoint = null;

#[ORM\OneToMany(mappedBy: 'partner', targetEntity: Contact::class)]
private Collection $contacts;
@@ -76,6 +102,13 @@ class Partner
#[ORM\OneToMany(mappedBy: 'partner', targetEntity: PartnerProduct::class)]
private Collection $partnerProducts;

#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private ?User $createdBy = null;

#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;

public function __construct(User $createdBy)
{
$this->createdBy = $createdBy;
@@ -93,6 +126,16 @@ class Partner
return $this->id;
}

public function getNavisionId(): ?int
{
return $this->navisionId;
}

public function setNavisionId(int $navisionId): void
{
$this->navisionId = $navisionId;
}

public function getName(): string
{
return $this->name;
@@ -368,4 +411,136 @@ class Partner
return $this;
}

public function getNameAddition(): ?string
{
return $this->nameAddition;
}

public function setNameAddition(?string $nameAddition): static
{
$this->nameAddition = $nameAddition;

return $this;
}

public function getAddressAddition(): ?string
{
return $this->addressAddition;
}

public function setAddressAddition(?string $addressAddition): static
{
$this->addressAddition = $addressAddition;

return $this;
}

public function getLanguage(): ?string
{
return $this->language;
}

public function setLanguage(?string $language): static
{
$this->language = $language;

return $this;
}

public function getCurrency(): ?string
{
return $this->currency;
}

public function setCurrency(?string $currency): static
{
$this->currency = $currency;

return $this;
}

public function getPaymentCondition(): ?string
{
return $this->paymentCondition;
}

public function setPaymentCondition(?string $paymentCondition): static
{
$this->paymentCondition = $paymentCondition;

return $this;
}

public function getDeliveryCondition(): ?string
{
return $this->deliveryCondition;
}

public function setDeliveryCondition(?string $deliveryCondition): static
{
$this->deliveryCondition = $deliveryCondition;

return $this;
}

public function getBusinessGroup(): ?string
{
return $this->businessGroup;
}

public function setBusinessGroup(?string $businessGroup): static
{
$this->businessGroup = $businessGroup;

return $this;
}

public function getVatBusinessGroup(): ?string
{
return $this->vatBusinessGroup;
}

public function setVatBusinessGroup(?string $vatBusinessGroup): static
{
$this->vatBusinessGroup = $vatBusinessGroup;

return $this;
}

public function getCreditLimit(): ?int
{
return $this->creditLimit;
}

public function setCreditLimit(?int $creditLimit): static
{
$this->creditLimit = $creditLimit;

return $this;
}

public function getRoutePoint(): ?string
{
return $this->routePoint;
}

public function setRoutePoint(?string $routePoint): static
{
$this->routePoint = $routePoint;

return $this;
}

public function getPhone(): ?string
{
return $this->phone;
}

public function setPhone(?string $phone): static
{
$this->phone = $phone;

return $this;
}

}

+ 163
- 1
src/Entity/Product.php Переглянути файл

@@ -17,7 +17,7 @@ class Product
private ?int $id = null;

#[ORM\Column(type: "integer", unique: true, nullable: true, options: ["unsigned" => true])]
protected int $navisionId;
protected ?int $navisionId;

#[ORM\Column(length: 255, unique: true)]
private ?string $name = null;
@@ -33,6 +33,36 @@ class Product
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
private ?User $createdBy = null;

#[ORM\Column]
private ?bool $blocked = null;

#[ORM\Column]
private ?float $inventory = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $baseUnit = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $buyUnit = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $sellUnit = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $trackingCode = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $productGroup = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $customsPosition = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $productBookingGroup = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $vatProductBookingGroup = null;

#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;

@@ -56,6 +86,8 @@ class Product

public function __construct(User $createdBy)
{
$this->blocked = false;
$this->inventory = 0.0;
$this->createdBy = $createdBy;
$this->createdAt = new \DateTimeImmutable();
$this->sales = new ArrayCollection();
@@ -71,6 +103,16 @@ class Product
return $this->id;
}

public function getNavisionId(): ?int
{
return $this->navisionId;
}

public function setNavisionId(int $navisionId): void
{
$this->navisionId = $navisionId;
}

public function getName(): ?string
{
return $this->name;
@@ -296,4 +338,124 @@ class Product

return $this;
}

public function isBlocked(): ?bool
{
return $this->blocked;
}

public function setBlocked(bool $blocked): static
{
$this->blocked = $blocked;

return $this;
}

public function getInventory(): ?float
{
return $this->inventory;
}

public function setInventory(float $inventory): static
{
$this->inventory = $inventory;

return $this;
}

public function getBaseUnit(): ?string
{
return $this->baseUnit;
}

public function setBaseUnit(?string $baseUnit): static
{
$this->baseUnit = $baseUnit;

return $this;
}

public function getBuyUnit(): ?string
{
return $this->buyUnit;
}

public function setBuyUnit(?string $buyUnit): static
{
$this->buyUnit = $buyUnit;

return $this;
}

public function getSellUnit(): ?string
{
return $this->sellUnit;
}

public function setSellUnit(?string $sellUnit): static
{
$this->sellUnit = $sellUnit;

return $this;
}

public function getTrackingCode(): ?string
{
return $this->trackingCode;
}

public function setTrackingCode(?string $trackingCode): static
{
$this->trackingCode = $trackingCode;

return $this;
}

public function getProductGroup(): ?string
{
return $this->productGroup;
}

public function setProductGroup(?string $productGroup): static
{
$this->productGroup = $productGroup;

return $this;
}

public function getCustomsPosition(): ?string
{
return $this->customsPosition;
}

public function setCustomsPosition(?string $customsPosition): static
{
$this->customsPosition = $customsPosition;

return $this;
}

public function getProductBookingGroup(): ?string
{
return $this->productBookingGroup;
}

public function setProductBookingGroup(?string $productBookingGroup): static
{
$this->productBookingGroup = $productBookingGroup;

return $this;
}

public function getVatProductBookingGroup(): ?string
{
return $this->vatProductBookingGroup;
}

public function setVatProductBookingGroup(?string $vatProductBookingGroup): static
{
$this->vatProductBookingGroup = $vatProductBookingGroup;

return $this;
}
}

+ 20
- 1
src/Factory/PartnerFactory.php Переглянути файл

@@ -31,6 +31,7 @@ use Zenstruck\Foundry\RepositoryProxy;
*/
final class PartnerFactory extends ModelFactory
{
private static $nameIndex = 0;

/**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
@@ -49,11 +50,29 @@ final class PartnerFactory extends ModelFactory
*/
protected function getDefaults(): array
{
$name = FakeValues::COMPANY_NAMES[self::$nameIndex % count(FakeValues::COMPANY_NAMES)];
$legalForm = self::faker()->randomElement(FakeValues::COMPANY_LEGAL_FORMS);
self::$nameIndex++;
return [
'name' => self::faker()->randomElement(FakeValues::COMPANY_NAMES)." ".self::faker()->randomElement(FakeValues::COMPANY_LEGAL_FORMS),
'name' => $name . " " . $legalForm,
'nameAddition' => self::faker()->text(20),
'type' => self::faker()->randomElement(PartnerType::cases()),
'description' => self::faker()->text(),
'street' => self::faker()->randomElement(FakeValues::STREETS),
'addressAddition' => self::faker()->randomElement(FakeValues::STREETS),
'phone' => self::faker()->phoneNumber(),
'language' => self::faker()->languageCode(),
'currency' => self::faker()->currencyCode(),
'paymentCondition' => self::faker()->randomElement(['30INV', '60BL', 'PP', 'CAD', 'SOFORT', '14INV', '5INV', '30INV14D2%', '']),
'deliveryCondition' => self::faker()->randomElement(['FCA', 'FOB', 'DDP', 'DAP', '']),
'businessGroup' => self::faker()->randomElement(['DE-DE', 'DRITT-DE', 'EU-DE', 'DRITT-DRITT', 'TRANSIT-DE', 'EU-DE-EU', '']),
'vatBusinessGroup' => self::faker()->randomElement(['DE-DE', 'DRITT-DE', 'EU-DE', 'DRITT-DRITT', 'TRANSIT-DE', 'EU-DE-EU', '']),
'creditLimit' => self::faker()->numberBetween(1000,1000000),
'routePoint' => self::faker()->randomElement([
'AT - SALZBURG', 'DE - TREBSEN/ MULDE', 'DE - GELSENKIRCHEN', 'CZ - PRAGUE', 'CH - BURGDORF', 'SI - PODNART', 'GB - ECCLES',
'SK - HUMENNÉ', 'IN - NHAVA SHEVA', 'CN - SHANGHAI', 'JP - NAGOYA', 'CO - FLORIDABLANCA', 'ES - ZARAGOZA', 'FR - HARNES',
'DE - HAMBURG', 'HU - NYÍREGYHÁZA', 'RO - TIMISOARA', 'SE - ROSERSBERG', 'TW - TAIPEY CITY', ''
]),
'streetNo' => self::faker()->numberBetween(1,1000),
'zip' => self::faker()->numberBetween(1000,10000),
'city' => self::faker()->randomElement(FakeValues::CITIES),


+ 10
- 0
src/Factory/ProductFactory.php Переглянути файл

@@ -50,6 +50,16 @@ final class ProductFactory extends ModelFactory
return [
'name' => self::faker()->word().random_int(1,999999),
'description' => self::faker()->text(),
'blocked' => self::faker()->boolean(),
'inventory' => self::faker()->numberBetween(0, 99999),
'baseUnit' => self::faker()->randomElement(['KG', 'SACK', 'STÜCK', '']),
'buyUnit' => self::faker()->randomElement(['KG', 'MT', 'DOSE', 'SACK', 'STÜCK', '']),
'sellUnit' => self::faker()->randomElement(['KG', 'MT', 'DOSE', 'SACK', 'STÜCK', '']),
'trackingCode' => self::faker()->randomElement(['CHARGE', '']),
'productGroup' => '',
'customsPosition' => self::faker()->numberBetween(10000000, 99999999),
'productBookingGroup' => self::faker()->randomElement(['VOLL', '0KOSTEN', '']),
'vatProductBookingGroup' => self::faker()->randomElement(['VOLL', 'OHNE', '']),
'createdBy' => UserFactory::random()
];
}


+ 24
- 9
src/Mapper/PartnerApiToEntityMapper.php Переглянути файл

@@ -33,6 +33,8 @@ class PartnerApiToEntityMapper implements MapperInterface

if ($dto->id) {
$entity = $this->repository->find($dto->id);
assert($entity instanceof Partner);

} else {
$user = $this->security->getUser();
assert($user instanceof User);
@@ -53,16 +55,29 @@ class PartnerApiToEntityMapper implements MapperInterface
$entity = $to;
assert($entity instanceof Partner);

$entity->setDescription($dto->description);
$entity->setName($dto->name);
$entity->setType($dto->partnerType);
$entity->setStreet($dto->street);
$entity->setStreetNo($dto->streetNo);
$entity->setZip($dto->zip);
$entity->setCity($dto->city);
$entity->setCountry($dto->country);
$entity->setWebsite($dto->website);
if ($entity->getNavisionId() === null) {
$entity->setName($dto->name);
$entity->setNameAddition($dto->nameAddition);
$entity->setType($dto->partnerType);
$entity->setStreet($dto->street);
$entity->setStreetNo($dto->streetNo);
$entity->setZip($dto->zip);
$entity->setCity($dto->city);
$entity->setCountry($dto->country);
$entity->setAddressAddition($dto->addressAddition);
$entity->setPhone($dto->phone);
$entity->setLanguage($dto->language);
$entity->setCurrency($dto->currency);
$entity->setPaymentCondition($dto->paymentCondition);
$entity->setDeliveryCondition($dto->deliveryCondition);
$entity->setBusinessGroup($dto->businessGroup);
$entity->setVatBusinessGroup($dto->vatBusinessGroup);
$entity->setCreditLimit($dto->creditLimit);
$entity->setRoutePoint($dto->routePoint);
}
$entity->setLogo($dto->logo);
$entity->setWebsite($dto->website);
$entity->setDescription($dto->description);

return $entity;
}


+ 12
- 0
src/Mapper/PartnerEntityToApiMapper.php Переглянути файл

@@ -44,7 +44,9 @@ class PartnerEntityToApiMapper implements MapperInterface
assert($entity instanceof Partner);
assert($dto instanceof PartnerApi);

$dto->navisionId = $entity->getNavisionId();
$dto->name = $entity->getName();
$dto->nameAddition = $entity->getNameAddition();
$dto->partnerType = $entity->getType();
$dto->description = $entity->getDescription();
$dto->street = $entity->getStreet();
@@ -55,6 +57,16 @@ class PartnerEntityToApiMapper implements MapperInterface
$dto->website = $entity->getWebsite();
$dto->logo = $entity->getLogo();
$dto->logoUrl = $this->fileUrlService->getFileUrl($entity->getLogo());
$dto->addressAddition = $entity->getAddressAddition();
$dto->language = $entity->getLanguage();
$dto->currency = $entity->getCurrency();
$dto->paymentCondition = $entity->getPaymentCondition();
$dto->deliveryCondition = $entity->getDeliveryCondition();
$dto->businessGroup = $entity->getBusinessGroup();
$dto->vatBusinessGroup = $entity->getVatBusinessGroup();
$dto->creditLimit = $entity->getCreditLimit();
$dto->routePoint = $entity->getRoutePoint();

$dto->createdByIri = $this->microMapper->map($entity->getCreatedBy(), UserApi::class, [
MicroMapperInterface::MAX_DEPTH => 1,
]);


+ 15
- 2
src/Mapper/ProductApiToEntityMapper.php Переглянути файл

@@ -49,8 +49,21 @@ class ProductApiToEntityMapper implements MapperInterface
$entity = $to;
assert($entity instanceof Product);

$entity->setName($dto->name);
$entity->setDescription($dto->description);
if ($entity->getNavisionId() === null) {
$entity->setName($dto->name);
$entity->setDescription($dto->description);
$entity->setBlocked($dto->blocked);
$entity->setInventory($dto->inventory);
$entity->setBaseUnit($dto->baseUnit);
$entity->setBuyUnit($dto->buyUnit);
$entity->setSellUnit($dto->sellUnit);
$entity->setTrackingCode($dto->trackingCode);
$entity->setProductGroup($dto->productGroup);
$entity->setProductBookingGroup($dto->productBookingGroup);
$entity->setVatProductBookingGroup($dto->vatProductBookingGroup);
$entity->setCustomsPosition($dto->customsPosition);
}

$entity->setImage($dto->image);

return $entity;


+ 10
- 0
src/Mapper/ProductEntityToApiMapper.php Переглянути файл

@@ -39,6 +39,16 @@ class ProductEntityToApiMapper implements MapperInterface

$dto->name = $entity->getName();
$dto->description = $entity->getDescription();
$dto->blocked = $entity->isBlocked();
$dto->inventory = $entity->getInventory();
$dto->baseUnit = $entity->getBaseUnit();
$dto->buyUnit = $entity->getBuyUnit();
$dto->sellUnit = $entity->getSellUnit();
$dto->trackingCode = $entity->getTrackingCode();
$dto->productGroup = $entity->getProductGroup();
$dto->vatProductBookingGroup = $entity->getVatProductBookingGroup();
$dto->productBookingGroup = $entity->getProductBookingGroup();
$dto->customsPosition = $entity->getCustomsPosition();
$dto->image = $entity->getImage();
$dto->imageUrl = $this->fileUrlService->getFileUrl($entity->getImage());
$dto->createdBy = $this->microMapper->map($entity->getCreatedBy(), UserApi::class, [


+ 198
- 0
src/Service/NavisionDataImportService.php Переглянути файл

@@ -0,0 +1,198 @@
<?php
/**
* @author Daniel Knudsen <d.knudsen@spawntree.de>
* @date 26.06.24
*/


namespace App\Service;


use App\Entity\Partner;
use App\Entity\Product;
use App\Entity\User;
use App\Enum\PartnerType;
use Doctrine\ORM\EntityManagerInterface;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Symfony\Component\HttpKernel\KernelInterface;

class NavisionDataImportService
{
private User $systemUser;

public function __construct(
private KernelInterface $kernel,
private EntityManagerInterface $em
)
{
$this->systemUser = $this->em->getRepository(User::class)->findOneBy(['email' => $_ENV['ADMIN_EMAIL']]);
if ($this->systemUser === null) {
throw new \Exception('System user not found!');
}
}

public function importCustomers()
{
$customers = $this->em->getRepository(Partner::class)->findBy(['type' => PartnerType::Customer]);
$customersByNavisionId = [];
/** @var Partner $customer */
foreach ($customers as $customer) {
if ($customer->getNavisionId() !== null) {
$customersByNavisionId[$customer->getNavisionId()] = $customer;
}
}

$data = $this->readExcelFile($this->kernel->getProjectDir()."/import/Kreditoren11 Stammdaten.xlsx");
$i = 0;
$customer = null;
foreach ($data as $row) {
if ($i >= 3) {
$name = $row[2];
$navisionId = $row[0];
if ($name !== "" && ctype_digit($navisionId)) {
if (array_key_exists($navisionId, $customersByNavisionId)) {
$customer = $customersByNavisionId[$navisionId];
} else {
$customer = new Partner($this->systemUser);
$customer->setType(PartnerType::Customer);
$customer->setNavisionId($navisionId);
}
$customer->setName($row[2]);
$customer->setNameAddition($row[3]);
$customer->setStreet($row[4]);
$customer->setAddressAddition($row[5]);
$customer->setZip($row[6]);
$customer->setCity($row[7]);
$customer->setCountry($row[8]);
$customer->setPhone($row[9]);
$customer->setLanguage($row[10]);
$customer->setCurrency($row[11]);
$customer->setPaymentCondition($row[12]);
$customer->setDeliveryCondition($row[13]);
$customer->setBusinessGroup($row[15]);
$customer->setVatBusinessGroup($row[16]);
$this->em->persist($customer);
}
}
$i++;
}
$this->em->flush();
}

public function importSuppliers()
{
$suppliers = $this->em->getRepository(Partner::class)->findBy(['type' => PartnerType::Supplier]);
$suppliersByNavisionId = [];
/** @var Partner $supplier */
foreach ($suppliers as $supplier) {
if ($supplier->getNavisionId() !== null) {
$suppliersByNavisionId[$supplier->getNavisionId()] = $supplier;
}
}

$data = $this->readExcelFile($this->kernel->getProjectDir()."/import/Debitoren11 Stammdaten.xlsx");
$i = 0;
$supplier = null;
foreach ($data as $row) {
if ($i >= 3) {
$name = $row[2];
$navisionId = $row[0];
if ($name !== "" && ctype_digit($navisionId)) {
if (array_key_exists($navisionId, $suppliersByNavisionId)) {
$supplier = $suppliersByNavisionId[$navisionId];
} else {
$supplier = new Partner($this->systemUser);
$supplier->setType(PartnerType::Supplier);
$supplier->setNavisionId($navisionId);
}
$supplier->setName($row[2]);
$supplier->setNameAddition($row[3]);
$supplier->setStreet($row[4]);
$supplier->setAddressAddition($row[5]);
$supplier->setZip($row[6]);
$supplier->setCity($row[7]);
$supplier->setCountry($row[8]);
$supplier->setPhone($row[9]);
$supplier->setLanguage($row[10]);
$supplier->setCurrency($row[11]);
$supplier->setPaymentCondition($row[12]);
$supplier->setCreditLimit($row[13]);
$supplier->setBusinessGroup($row[15]);
$supplier->setVatBusinessGroup($row[16]);
$supplier->setRoutePoint($row[17]);
$this->em->persist($supplier);
}
}
$i++;
}
$this->em->flush();
}

public function importProducts()
{
$products = $this->em->getRepository(Product::class)->findAll();
$productsByNavisionId = [];
/** @var Product $product */
foreach ($products as $product) {
if ($product->getNavisionId() !== null) {
$productsByNavisionId[$product->getNavisionId()] = $product;
}
}

$data = $this->readExcelFile($this->kernel->getProjectDir()."/import/Artikel11 Stammdaten.xlsx");
$i = 0;
$product = null;
foreach ($data as $row) {
if ($i >= 3) {
$name = $row[2];
$navisionId = $row[0];
if ($name !== "" && ctype_digit($navisionId)) {
if (array_key_exists($navisionId, $productsByNavisionId)) {
$product = $productsByNavisionId[$navisionId];
} else {
$product = new Product($this->systemUser);
$product->setNavisionId($navisionId);
}
$product->setName($row[2]);
$product->setDescription($row[3]);
$product->setBlocked($row[4] === "Ja");
$product->setInventory($row[5]);
$product->setBaseUnit($row[6]);
$product->setBuyUnit($row[7]);
$product->setSellUnit($row[8]);
$product->setTrackingCode($row[9]);
$product->setProductGroup($row[10]);
$product->setCustomsPosition($row[11]);
$product->setProductBookingGroup($row[12]);
$product->setVatProductBookingGroup($row[13]);
$this->em->persist($product);
}
}
$i++;
}
$this->em->flush();
}

private function readExcelFile(string $filePath): array
{
// Load the spreadsheet
$spreadsheet = IOFactory::load($filePath);
$sheet = $spreadsheet->getActiveSheet();
$data = [];

// Iterate through each row in the spreadsheet
foreach ($sheet->getRowIterator() as $row) {
$rowData = [];
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false);

foreach ($cellIterator as $cell) {
$rowData[] = $cell->getValue();
}

$data[] = $rowData;
}

return $data;
}
}

Завантаження…
Відмінити
Зберегти