diff --git a/src/new/config/reference.php b/src/new/config/reference.php index a52f4b18b..b8fa52801 100644 --- a/src/new/config/reference.php +++ b/src/new/config/reference.php @@ -476,7 +476,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * datetime?: array{ * default_format?: scalar|Param|null, // Default: "Y-m-d\\TH:i:sP" * default_deserialization_formats?: list, - * default_timezone?: scalar|Param|null, // Default: "Europe/Berlin" + * default_timezone?: scalar|Param|null, // Default: "UTC" * cdata?: scalar|Param|null, // Default: true * }, * array_collection?: array{ @@ -576,7 +576,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * datetime?: array{ * default_format?: scalar|Param|null, // Default: "Y-m-d\\TH:i:sP" * default_deserialization_formats?: list, - * default_timezone?: scalar|Param|null, // Default: "Europe/Berlin" + * default_timezone?: scalar|Param|null, // Default: "UTC" * cdata?: scalar|Param|null, // Default: true * }, * array_collection?: array{ @@ -2433,7 +2433,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * length?: scalar|Param|null, // Default: 5 * width?: scalar|Param|null, // Default: 130 * height?: scalar|Param|null, // Default: 50 - * font?: scalar|Param|null, // Default: "/data/www/new/vendor/gregwar/captcha-bundle/DependencyInjection/../Generator/Font/captcha.ttf" + * font?: scalar|Param|null, // Default: "/application/src/new/vendor/gregwar/captcha-bundle/DependencyInjection/../Generator/Font/captcha.ttf" * keep_value?: scalar|Param|null, // Default: false * charset?: scalar|Param|null, // Default: "abcdefhjkmnprstuvwxyz23456789" * as_file?: scalar|Param|null, // Default: false diff --git a/src/new/src/PSC/Shop/OrderBundle/Interface/IUploadMode.php b/src/new/src/PSC/Shop/OrderBundle/Interface/IUploadMode.php deleted file mode 100644 index 5f0d1ff52..000000000 --- a/src/new/src/PSC/Shop/OrderBundle/Interface/IUploadMode.php +++ /dev/null @@ -1,12 +0,0 @@ -productService = $productService; $this->productTypeRegistry = $productTypeRegistry; $this->productHydrate = $productHydrate; - $this->uploadObjectTypes = $uploadObjectTypes; + $this->uploadOptionTypes = $uploadOptionTypes; } public function toDb( @@ -100,7 +100,9 @@ class Position extends Base /** * Plugin Special Savings */ - if ($this->productTypeRegistry->getProductType($position->getProduct()->getSpecialProductTypeObject()->getTyp())) { + if ($this->productTypeRegistry->getProductType( + $position->getProduct()->getSpecialProductTypeObject()->getTyp(), + )) { $specialProductTransformer = $this->productTypeRegistry ->getProductType($position->getProduct()->getSpecialProductTypeObject()->getTyp()) ->getPositionProductTransformer(); @@ -188,8 +190,8 @@ class Position extends Base $position->setCustomerInfo((string) $positionDoc->getCustomerInfo()); if ($positionDoc->getUploadMode() != '') { - foreach ($this->uploadObjectTypes as $object) { - if ($positionDoc->getUploadMode() == $object->getCode()) { + foreach ($this->uploadOptionTypes as $object) { + if ($positionDoc->getUploadMode() == $object->getType()) { $object->getTransformer()->fromDb($position, $pos, $positionDoc); } } diff --git a/src/new/src/PSC/Shop/ProductBundle/Api/Product/GetUploadOptions.php b/src/new/src/PSC/Shop/ProductBundle/Api/Product/GetUploadOptions.php new file mode 100644 index 000000000..41f396056 --- /dev/null +++ b/src/new/src/PSC/Shop/ProductBundle/Api/Product/GetUploadOptions.php @@ -0,0 +1,49 @@ +entityManager->getRepository(Product::class)->findOneBy(['uuid' => $uuid]); + + if (!$product) { + return $this->json(new NotFound('Product not found'), 404); + } + + $productDoc = $this->documentManager + ->getRepository(\PSC\Shop\EntityBundle\Document\Product::class) + ->findOneBy(['uid' => $product->getUID()]); + + $result = []; + foreach ($this->uploadOptions as $option) { + if ($option->isEnabled($product, $productDoc)) { + $result[] = [ + 'type' => $option->getType(), + 'label' => $option->getLabel(), + 'contentUrl' => $option->getContentUrl(), + ]; + } + } + + return $this->json(['data' => $result]); + } +} diff --git a/src/new/src/PSC/Shop/ProductBundle/Interfaces/IUploadOption.php b/src/new/src/PSC/Shop/ProductBundle/Interfaces/IUploadOption.php new file mode 100644 index 000000000..c96de360c --- /dev/null +++ b/src/new/src/PSC/Shop/ProductBundle/Interfaces/IUploadOption.php @@ -0,0 +1,26 @@ +isUploadCenter(); + } +} diff --git a/src/new/src/PSC/Shop/ProductBundle/Service/UploadOption/EmailUpload.php b/src/new/src/PSC/Shop/ProductBundle/Service/UploadOption/EmailUpload.php new file mode 100644 index 000000000..e55f5aeeb --- /dev/null +++ b/src/new/src/PSC/Shop/ProductBundle/Service/UploadOption/EmailUpload.php @@ -0,0 +1,39 @@ +isUploadEmail(); + } +} diff --git a/src/new/src/PSC/Shop/ProductBundle/Transformer/Order/Position/IUploadOptionTransformer.php b/src/new/src/PSC/Shop/ProductBundle/Transformer/Order/Position/IUploadOptionTransformer.php new file mode 100644 index 000000000..3fbae1339 --- /dev/null +++ b/src/new/src/PSC/Shop/ProductBundle/Transformer/Order/Position/IUploadOptionTransformer.php @@ -0,0 +1,13 @@ +setUploadTypeObject(new PSCMail()); } - public function toDb(Position $position, Orderpos $posEntity, PosDoc $posDoc): void - { - } + public function toDb(Position $position, Orderpos $posEntity, PosDoc $posDoc): void {} } diff --git a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/lib/uploadOptionRegistry.ts b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/lib/uploadOptionRegistry.ts new file mode 100644 index 000000000..ba995dec1 --- /dev/null +++ b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/lib/uploadOptionRegistry.ts @@ -0,0 +1,21 @@ +import React from 'react' +import {Pos} from '../model/pos' +import {UploadFile} from '../model/upload' + +export interface UploadOptionRendererProps { + pos: Pos + files: UploadFile[] + onUploaded: (f: UploadFile) => void +} + +export type UploadOptionRenderer = (props: UploadOptionRendererProps) => React.ReactElement | null + +const registry = new Map() + +export const registerUploadOptionRenderer = (type: string, renderer: UploadOptionRenderer) => { + registry.set(type, renderer) +} + +export const getUploadOptionRenderer = (type: string): UploadOptionRenderer | undefined => { + return registry.get(type) +} diff --git a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/main.tsx b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/main.tsx index 3b1cd99f3..ed64d68d3 100644 --- a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/main.tsx +++ b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/main.tsx @@ -1,5 +1,6 @@ import "./assets/index.css" import "reflect-metadata"; +import "./modules/uploadOptions"; import * as $ from "jquery"; import { App } from "./app/app"; diff --git a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/pos.ts b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/pos.ts index a49bd19ab..9b8099dd0 100644 --- a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/pos.ts +++ b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/pos.ts @@ -1,6 +1,7 @@ import {v4 as uuidv4} from 'uuid' import {Product} from "./product" import {Price} from "./price" +import {UploadFile} from "./upload" export class Pos { uuid: String = "" @@ -8,6 +9,8 @@ export class Pos { status: Number = 10 count: Number = 1 price: Price = new Price() + uploads: UploadFile[] = [] + uploadMode: string = '' constructor() { this.uuid = uuidv4() @@ -17,7 +20,16 @@ export class Pos { this.count = item.price.count this.status = item.status this.uuid = item.uuid + this.uploadMode = item.uploadMode ?? '' this.price.parseFromJson(item.price) this.product.parseFromJson(item.product) + this.uploads = (item.uploads ?? []).map((u: any) => { + const f = new UploadFile() + f.uuid = u.uuid + f.name = u.fileName + f.path = u.path + f.typ = u.typ + return f + }) } } \ No newline at end of file diff --git a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/upload.ts b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/upload.ts new file mode 100644 index 000000000..91b10348f --- /dev/null +++ b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/upload.ts @@ -0,0 +1,6 @@ +export class UploadFile { + uuid: string = '' + name: string = '' + path: string = '' + typ: string = '' +} diff --git a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/uploadOption.ts b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/uploadOption.ts new file mode 100644 index 000000000..0216af27f --- /dev/null +++ b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/model/uploadOption.ts @@ -0,0 +1,5 @@ +export class UploadOption { + type: string = '' + label: string = '' + contentUrl: string | null = null +} diff --git a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/modules/positions/PosComponent.tsx b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/modules/positions/PosComponent.tsx index c5de42855..be7324853 100644 --- a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/modules/positions/PosComponent.tsx +++ b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/modules/positions/PosComponent.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useEffect, useState} from 'react' import * as PropTypes from "prop-types" import {Pos} from "../../model/pos" import Button from '../base/Button' @@ -6,10 +6,22 @@ import EditPositionComponent from './EditPositionComponent' import { Shop } from '../../model/shop' import Currency from '../base/Currency' import { Button as FlowbiteButton } from "flowbite-react" +import ProductService from '../../services/product' +import {UploadOption} from '../../model/uploadOption' +import UploadOptionModal from './UploadOptionModal' const PosComponent = ({index, pos, delPos, changePos, shop}) => { + const [uploadOptions, setUploadOptions] = useState([]) + + useEffect(() => { + if (pos.product.uuid) { + const productService = new ProductService() + productService.getUploadOptions(pos.product).then(setUploadOptions) + } + }, [pos.product.uuid]) + const deletePos = (uuid: String) => { delPos(uuid) } @@ -36,7 +48,15 @@ const PosComponent = ({index, pos, delPos, changePos, shop}) => { - + + {uploadOptions.length > 0 && ( +
+ {uploadOptions.map(option => ( + + ))} +
+ )} +
diff --git a/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/modules/positions/UploadOptionModal.tsx b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/modules/positions/UploadOptionModal.tsx new file mode 100644 index 000000000..7721250e9 --- /dev/null +++ b/src/new/var/plugins/System/PSC/Invoice/InvoiceTS/src/modules/positions/UploadOptionModal.tsx @@ -0,0 +1,41 @@ +import React, {useState} from 'react' +import {Modal, Button as FlowbiteButton} from 'flowbite-react' +import {UploadOption} from '../../model/uploadOption' +import {UploadFile} from '../../model/upload' +import {Pos} from '../../model/pos' +import {getUploadOptionRenderer} from '../../lib/uploadOptionRegistry' + +const UploadOptionModal = ({option, pos}: {option: UploadOption, pos: Pos}) => { + const [show, setShow] = useState(false) + const [files, setFiles] = useState(pos.uploads) + + const Renderer = getUploadOptionRenderer(option.type) + + return ( + <> + setShow(true)} title={option.label}> + {option.label} + + + setShow(false)}> + {option.label} — {pos.product.title} + + {option.contentUrl ? ( +