MatrixProduct: Add function to create missing Variants, some bugfixes

This commit is contained in:
Andreas Palm 2024-04-24 15:14:35 +02:00
parent df4c8bd89a
commit db1ab2baf0
18 changed files with 1669 additions and 1106 deletions

View File

@ -3,6 +3,7 @@
namespace Xentral\Modules\Article;
use Xentral\Core\DependencyInjection\ContainerInterface;
use Xentral\Modules\Article\Service\ArticleService;
use Xentral\Modules\Article\Service\SellingPriceService;
use Xentral\Modules\Article\Gateway\ArticleGateway;
use Xentral\Modules\Article\Service\CurrencyConversionService;
@ -17,6 +18,7 @@ final class Bootstrap
{
return [
'ArticleGateway' => 'onInitArticleGateway',
'ArticleService' => 'onInitArticleService',
'PurchasePriceService' => 'onInitPurchasePriceService',
'SellingPriceService' => 'onInitSellingPriceService',
'CurrencyConversionService' => 'onInitCurrencyConversionService',
@ -65,4 +67,17 @@ final class Bootstrap
return new CurrencyConversionService($app->erp);
}
/**
* @param ContainerInterface $container
*
* @return ArticleService
*/
public static function onInitArticleService(ContainerInterface $container)
{
/** @var \ApplicationCore $app */
$app = $container->get('LegacyApplication');
return new ArticleService($app);
}
}

View File

@ -0,0 +1,131 @@
<?php
namespace Xentral\Modules\Article\Service;
use ApplicationCore;
use Xentral\Components\Database\Database;
class ArticleService
{
private ApplicationCore $app;
public function __construct(ApplicationCore $app)
{
$this->app = $app;
}
function CopyArticle(int $id, bool $purchasePrices, bool $sellingPrices, bool $files, bool $properties,
bool $instructions, bool $partLists, bool $customFields, string $newArticleNumber = '')
{
$this->app->DB->MysqlCopyRow('artikel','id',$id);
$idnew = $this->app->DB->GetInsertID();
$steuersatz = $this->app->DB->Select("SELECT steuersatz FROM artikel WHERE id = '$id' LIMIT 1");
if($steuersatz == ''){
$steuersatz = -1.00;
$this->app->DB->Update("UPDATE artikel SET steuersatz = '$steuersatz' WHERE id = '$idnew' LIMIT 1");
}
$this->app->DB->Update("UPDATE artikel SET nummer='$newArticleNumber' WHERE id='$idnew' LIMIT 1");
if($this->app->DB->Select("SELECT variante_kopie FROM artikel WHERE id = '$id' LIMIT 1"))
$this->app->DB->Update("UPDATE artikel SET variante = 1, variante_von = '$id' WHERE id = '$idnew' LIMIT 1");
if($partLists){
// wenn stueckliste
$stueckliste = $this->app->DB->Select("SELECT stueckliste FROM artikel WHERE id='$id' LIMIT 1");
if($stueckliste==1)
{
$artikelarr = $this->app->DB->SelectArr("SELECT * FROM stueckliste WHERE stuecklistevonartikel='$id'");
$cartikelarr = $artikelarr?count($artikelarr):0;
for($i=0;$i<$cartikelarr;$i++)
{
$sort = $artikelarr[$i]['sort'];
$artikel = $artikelarr[$i]['artikel'];
$referenz = $artikelarr[$i]['referenz'];
$place = $artikelarr[$i]['place'];
$layer = $artikelarr[$i]['layer'];
$stuecklistevonartikel = $idnew;
$menge = $artikelarr[$i]['menge'];
$firma = $artikelarr[$i]['firma'];
$this->app->DB->Insert("INSERT INTO stueckliste (id,sort,artikel,referenz,place,layer,stuecklistevonartikel,menge,firma) VALUES
('','$sort','$artikel','$referenz','$place','$layer','$stuecklistevonartikel','$menge','$firma')");
}
}
}
if($purchasePrices){
$einkaufspreise = $this->app->DB->SelectArr("SELECT id FROM einkaufspreise WHERE artikel = '$id'");
if($einkaufspreise){
foreach($einkaufspreise as $preis){
$neuereinkaufspreis = $this->app->DB->MysqlCopyRow("einkaufspreise", "id", $preis['id']);
$this->app->DB->Update("UPDATE einkaufspreise SET artikel = '$idnew' WHERE id = '$neuereinkaufspreis' LIMIT 1");
}
}
}
if($sellingPrices){
$verkaufspreise = $this->app->DB->SelectArr("SELECT id FROM verkaufspreise WHERE artikel = '$id'");
if($verkaufspreise){
foreach($verkaufspreise as $preis){
$neuerverkaufspreis = $this->app->DB->MysqlCopyRow("verkaufspreise", "id", $preis['id']);
$this->app->DB->Update("UPDATE verkaufspreise SET artikel = '$idnew' WHERE id = '$neuerverkaufspreis' LIMIT 1");
}
}
}
if($files){
$dateien = $this->app->DB->SelectArr("SELECT DISTINCT datei FROM datei_stichwoerter WHERE parameter = '$id' AND objekt = 'Artikel'");
$datei_stichwoerter = $this->app->DB->SelectArr("SELECT id,datei FROM datei_stichwoerter WHERE parameter = '$id' AND objekt = 'Artikel'");
if($dateien){
foreach($dateien as $datei){
$titel = $this->app->DB->Select("SELECT titel FROM datei WHERE id='".$datei['datei']."' LIMIT 1");
$beschreibung = $this->app->DB->Select("SELECT beschreibung FROM datei WHERE id='".$datei['datei']."' LIMIT 1");
$nummer = $this->app->DB->Select("SELECT nummer FROM datei WHERE id='".$datei['datei']."' LIMIT 1");
$name = $this->app->DB->Select("SELECT dateiname FROM datei_version WHERE datei='".$this->app->DB->real_escape_string($datei['datei'])."' ORDER by version DESC LIMIT 1");
$ersteller = $this->app->User->GetName();
$tmpnewdateiid = $this->app->erp->CreateDatei($name,$titel,$beschreibung,$nummer,$this->app->erp->GetDateiPfad($datei['datei']),$ersteller);
$datei_mapping[$datei['datei']] = $tmpnewdateiid;
}
}
if($datei_stichwoerter){
foreach($datei_stichwoerter as $datei){
$neuesstichwort = $this->app->DB->MysqlCopyRow("datei_stichwoerter", "id", $datei['id']);
$newdatei = $datei_mapping[$datei['datei']];
$this->app->DB->Update("UPDATE datei_stichwoerter SET datei='$newdatei', parameter = '$idnew', objekt = 'Artikel' WHERE id = '$neuesstichwort' LIMIT 1");
}
}
}
if($properties){
$aeigenschaften = $this->app->DB->SelectArr("SELECT id FROM artikeleigenschaftenwerte WHERE artikel = '$id'");
if($aeigenschaften){
foreach($aeigenschaften as $eigenschaft){
$neue_eigenschaft = $this->app->DB->MysqlCopyRow("artikeleigenschaftenwerte", "id", $eigenschaft['id']);
$this->app->DB->Update("UPDATE artikeleigenschaftenwerte SET artikel = '$idnew' WHERE id = '$neue_eigenschaft' LIMIT 1");
}
}
}
if($instructions){
$arbeitsanweisungen = $this->app->DB->SelectArr("SELECT id FROM artikel_arbeitsanweisung WHERE artikel = '$id'");
if($arbeitsanweisungen){
foreach($arbeitsanweisungen as $anweisung){
$neue_anweisung = $this->app->DB->MysqlCopyRow("artikel_arbeitsanweisung", "id", $anweisung['id']);
$this->app->DB->Update("UPDATE artikel_arbeitsanweisung SET artikel = '$idnew' WHERE id = '$neue_anweisung' LIMIT 1");
}
}
}
if($customFields){
$freifelderuebersetzungen = $this->app->DB->SelectArr("SELECT id FROM artikel_freifelder WHERE artikel = '$id'");
if($freifelderuebersetzungen){
$this->app->DB->Insert("INSERT INTO artikel_freifelder (artikel, sprache, nummer, wert) SELECT '$idnew', sprache, nummer, wert FROM artikel_freifelder WHERE artikel = '$id'");
}
}
return $idnew;
}
}

View File

@ -279,6 +279,15 @@ final class MatrixProductGateway
$sql = "DELETE FROM matrixprodukt_optionen_zu_artikel WHERE artikel = :id";
$this->db->perform($sql, ['id' => $variantId]);
}
public function GetSuffixStringForOptionSet(array $optionIds) : string {
$sql = "SELECT GROUP_CONCAT(IFNULL(NULLIF(mao.articlenumber_suffix,''), mao.id) ORDER BY mag.sort, mag.id SEPARATOR '_')
FROM matrixprodukt_eigenschaftenoptionen_artikel mao
JOIN matrixprodukt_eigenschaftengruppen_artikel mag ON mao.gruppe = mag.id
WHERE mao.id IN (:idList)";
$res = $this->db->fetchValue($sql, ['idList' => $optionIds]);
return $res;
}
//endregion
//region Translations

View File

@ -144,6 +144,13 @@ final class MatrixProductService
//endregion
//region Variants
public function GetVariantIdByOptionSet(array $optionIds) : ?int {
return $this->gateway->GetVariantIdByOptions($optionIds);
}
public function GetSuffixStringForOptionSet(array $optionIds) : string
{
return $this->gateway->GetSuffixStringForOptionSet($optionIds);
}
public function SaveVariant(int $articleId, int $variantId, array $optionIds, ?int $oldVariantId = null) : bool|string {
if ($oldVariantId != null && $oldVariantId != $variantId) {
$this->gateway->ReplaceVariant($oldVariantId, $variantId);
@ -166,6 +173,7 @@ final class MatrixProductService
public function DeleteVariant(int $variantId) : void {
$this->gateway->DeleteVariantById($variantId);
$this->articleGateway->SetVariantStatus($variantId, null);
}
//endregion

View File

@ -13,6 +13,7 @@ import GroupEdit from "./GroupEdit.vue";
import OptionEdit from "./OptionEdit.vue";
import Variant from "./Variant.vue";
import Translation from "./Translation.vue";
import CreateMissing from "./CreateMissing.vue";
const model = ref(null);
@ -75,6 +76,7 @@ function onClose() {
<GroupEdit v-else-if="model.action === 'groupEdit'" v-bind="model" @close="onClose" @save="onGroupSave" />
<OptionEdit v-else-if="model.action === 'optionEdit'" v-bind="model" @close="onClose" @save="onSave" />
<Variant v-else-if="model.action === 'variantEdit'" v-bind="model" @close="onClose" @save="onSave" />
<CreateMissing v-else-if="model.action === 'createMissing'" v-bind="model" @close="onClose" @save="onSave" />
<Translation v-else-if="model.action === 'translationEdit'" v-bind="model" @close="onClose" @save="onSave" />
</template>
</template>

View File

@ -0,0 +1,46 @@
<script setup>
import Button from "primevue/button";
import Dialog from "primevue/dialog";
import MultiSelect from "primevue/multiselect";
import {onMounted, ref} from "vue";
import axios from "axios";
import {AlertErrorHandler} from "@res/js/ajaxErrorHandler";
const props = defineProps({
articleId: String,
});
const emit = defineEmits(['save', 'close']);
const model = ref({});
onMounted(async () => {
model.value = await axios.get('index.php?module=matrixprodukt&action=artikel&cmd=createMissing', {
params: {...props}
}).then(response => { return {...props, ...response.data}})
})
async function save() {
await axios.post('index.php?module=matrixprodukt&action=artikel&cmd=createMissing', {...props, ...model.value})
.catch(AlertErrorHandler)
.then(() => {emit('save')});
}
</script>
<template>
<Dialog visible modal header="Variante" style="width: 500px" @update:visible="emit('close')">
<div class="grid gap-1" style="grid-template-columns: 25% 75%;">
<template v-for="group in model.groups">
<label>{{ group.name }}</label>
<MultiSelect v-model="group.selected" :options="group.options" optionLabel="name" optionValue="value" />
</template>
</div>
<template #footer>
<Button label="ABBRECHEN" @click="emit('close')" />
<Button label="ERSTELLEN" @click="save" />
</template>
</Dialog>
</template>
<style scoped>
</style>

View File

@ -5,9 +5,11 @@
*/
@import "autocomplete.css";
@import "checkbox.css";
@import "dialog.css";
@import "dropdown.css";
@import "listbox.css";
@import "multiselect.css";
.p-component-overlay {
background-color: rgba(170,170,170,0.7);
@ -24,6 +26,6 @@
}
.p-icon {
width: 1rem;
height: 1rem;
width: 1em;
height: 1em;
}

View File

@ -0,0 +1,78 @@
@layer primevue {
.p-checkbox {
position: relative;
display: inline-flex;
user-select: none;
vertical-align: bottom;
}
.p-checkbox-input {
cursor: pointer;
}
.p-checkbox-box {
display: flex;
justify-content: center;
align-items: center;
}
}
.p-checkbox {
width: 20px;
height: 20px;
}
.p-checkbox .p-checkbox-input {
appearance: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
opacity: 0;
z-index: 1;
outline: 0 none;
border: 2px solid #ced4da;
border-radius: 4px;
}
.p-checkbox .p-checkbox-box {
border: 2px solid #ced4da;
background: #ffffff;
width: 20px;
height: 20px;
color: #212529;
border-radius: 4px;
transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
outline-color: transparent;
}
.p-checkbox .p-checkbox-box .p-checkbox-icon {
transition-duration: 0.15s;
color: #ffffff;
font-size: 14px;
}
.p-checkbox .p-checkbox-box .p-checkbox-icon.p-icon {
width: 14px;
height: 14px;
}
.p-checkbox .p-checkbox-box.p-highlight {
border-color: var(--button-primary-background);
background: var(--button-primary-background);
}
.p-checkbox:not(.p-disabled):has(.p-checkbox-input:hover) .p-checkbox-box {
border-color: #ced4da;
}
.p-checkbox:not(.p-disabled):has(.p-checkbox-input:hover) .p-checkbox-box.p-highlight {
border-color: #0062cc;
background: #0062cc;
color: #ffffff;
}
.p-checkbox:not(.p-disabled):has(.p-checkbox-input:focus-visible) .p-checkbox-box {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
border-color: #007bff;
}
.p-checkbox.p-invalid > .p-checkbox-box {
border-color: #dc3545;
}

View File

@ -0,0 +1,30 @@
.p-icon {
display: inline-block;
}
.p-icon-spin {
-webkit-animation: p-icon-spin 2s infinite linear;
animation: p-icon-spin 2s infinite linear;
}
@-webkit-keyframes p-icon-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes p-icon-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

View File

@ -0,0 +1,247 @@
@layer primevue {
.p-multiselect {
display: inline-flex;
cursor: pointer;
user-select: none;
}
.p-multiselect-trigger {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.p-multiselect-label-container {
overflow: hidden;
flex: 1 1 auto;
cursor: pointer;
}
.p-multiselect-label {
display: block;
white-space: nowrap;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
}
.p-multiselect-label-empty {
overflow: hidden;
visibility: hidden;
}
.p-multiselect-token {
cursor: default;
display: inline-flex;
align-items: center;
flex: 0 0 auto;
}
.p-multiselect-token-icon {
cursor: pointer;
}
.p-multiselect .p-multiselect-panel {
min-width: 100%;
}
.p-multiselect-items-wrapper {
overflow: auto;
}
.p-multiselect-items {
margin: 0;
padding: 0;
list-style-type: none;
}
.p-multiselect-item {
cursor: pointer;
display: flex;
align-items: center;
font-weight: normal;
white-space: nowrap;
position: relative;
overflow: hidden;
}
.p-multiselect-item-group {
cursor: auto;
}
.p-multiselect-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.p-multiselect-filter-container {
position: relative;
flex: 1 1 auto;
}
.p-multiselect-filter-icon {
position: absolute;
top: 50%;
margin-top: -0.5rem;
}
.p-multiselect-filter-container .p-inputtext {
width: 100%;
}
.p-multiselect-close {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
overflow: hidden;
position: relative;
margin-left: auto;
}
.p-fluid .p-multiselect {
display: flex;
}
}
.p-multiselect {
background: #ffffff;
border: 1px solid #ced4da;
transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
border-radius: 4px;
outline-color: transparent;
}
.p-multiselect:not(.p-disabled):hover {
border-color: #ced4da;
}
.p-multiselect:not(.p-disabled).p-focus {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
border-color: #007bff;
}
.p-multiselect .p-multiselect-label {
padding: 0.25rem 0.75rem;
transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.p-multiselect .p-multiselect-label.p-placeholder {
color: #6c757d;
}
.p-multiselect.p-multiselect-chip .p-multiselect-token {
padding: 0.25rem 0.75rem;
margin-right: 0.5rem;
background: #dee2e6;
color: #212529;
border-radius: 16px;
}
.p-multiselect.p-multiselect-chip .p-multiselect-token .p-multiselect-token-icon {
margin-left: 0.5rem;
}
.p-multiselect .p-multiselect-trigger {
background: transparent;
color: #495057;
width: 2.357rem;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.p-multiselect.p-invalid.p-component {
border-color: #dc3545;
}
.p-inputwrapper-filled.p-multiselect.p-multiselect-chip .p-multiselect-label {
padding: 0.25rem 0.75rem;
}
.p-multiselect-panel {
background: #ffffff;
color: var(--grey);
border: 1px solid var(--fieldset-dark);
border-radius: 4px;
box-shadow: none;
}
.p-multiselect-panel .p-multiselect-header {
padding: 3px;
border-bottom: 1px solid #dee2e6;
color: #212529;
background: #efefef;
margin: 0;
border-top-right-radius: 4px;
border-top-left-radius: 4px;
}
.p-multiselect-panel .p-multiselect-header .p-multiselect-filter-container .p-inputtext {
padding-right: 1.75rem;
}
.p-multiselect-panel .p-multiselect-header .p-multiselect-filter-container .p-multiselect-filter-icon {
right: 0.75rem;
color: #495057;
}
.p-multiselect-panel .p-multiselect-header .p-checkbox {
margin-right: 0.5rem;
}
.p-multiselect-panel .p-multiselect-header .p-multiselect-close {
margin-left: 0.5rem;
width: 1rem;
height: 1rem;
color: #6c757d;
border: 0 none;
background: transparent;
border-radius: 50%;
transition: box-shadow 0.15s;
outline-color: transparent;
}
.p-multiselect-panel .p-multiselect-header .p-multiselect-close:enabled:hover {
color: #495057;
border-color: transparent;
background: transparent;
}
.p-multiselect-panel .p-multiselect-header .p-multiselect-close:focus-visible {
outline: 0 none;
outline-offset: 0;
box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);
}
.p-multiselect-panel .p-multiselect-items {
padding: 0;
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item {
margin: 0;
padding: 3px;
border: 0 none;
color: #212529;
background: transparent;
transition: box-shadow 0.15s;
border-radius: 0;
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item:first-child {
margin-top: 0;
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item:last-child {
margin-bottom: 0;
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item.p-highlight {
/*color: #ffffff;*/
/*background: var(--button-primary-background);*/
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item.p-highlight.p-focus {
/*background: var(--button-primary-background);*/
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item:not(.p-highlight):not(.p-disabled).p-focus {
color: #212529;
background: #e9ecef;
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item .p-checkbox {
margin-right: 0.5rem;
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-item-group {
margin: 0;
padding: 0.75rem 1rem;
color: #212529;
background: #ffffff;
font-weight: 600;
}
.p-multiselect-panel .p-multiselect-items .p-multiselect-empty-message {
padding: 0.5rem 1.5rem;
color: #212529;
background: transparent;
}

1
www/dist/assets/entry-078d65ea.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,13 @@
{
"classes/Modules/MatrixProduct/www/js/entry.css": {
"file": "assets/entry-3dab8f30.css",
"file": "assets/entry-078d65ea.css",
"src": "classes/Modules/MatrixProduct/www/js/entry.css"
},
"classes/Modules/MatrixProduct/www/js/entry.jsx": {
"css": [
"assets/entry-3dab8f30.css"
"assets/entry-078d65ea.css"
],
"file": "assets/modules/MatrixProduct-8f254ff6.js",
"file": "assets/modules/MatrixProduct-2b98726c.js",
"isEntry": true,
"src": "classes/Modules/MatrixProduct/www/js/entry.jsx"
}

View File

@ -31,6 +31,7 @@ class Artikel extends GenArtikel {
/** @var Application $app */
var $app;
const MODULE_NAME = 'Article';
protected \Xentral\Modules\Article\Service\ArticleService $service;
public function TableSearch($app, $name, $erlaubtevars)
{
@ -1882,6 +1883,7 @@ class Artikel extends GenArtikel {
if($intern){
return;
}
$this->service = $this->app->Container->get('ArticleService');
$this->app->ActionHandlerInit($this);
@ -5202,157 +5204,11 @@ class Artikel extends GenArtikel {
$freifelderuebersetzung = 0;
}
$data = array($id, $einkaufspreise, $verkaufspreise, $dateien, $eigenschaften, $anweisungen, $stuecklisten, $freifelderuebersetzung);
$idnew = $this->ArtikelCopy($data, true);
$idnew = $this->service->CopyArticle($id, $einkaufspreise, $verkaufspreise, $dateien, $eigenschaften, $anweisungen, $stuecklisten, $freifelderuebersetzung);
echo json_encode(array('status'=>1,'url'=>'index.php?module=artikel&action=edit&id='.$idnew));
$this->app->ExitXentral();
}
function ArtikelCopy($data = null, $return = false)
{
//$id = $this->app->Secure->GetGET("id");
$id = $data[0];
$einkaufspreise = $data[1];
$verkaufspreise = $data[2];
$dateien = $data[3];
$eigenschaften = $data[4];
$anweisungen = $data[5];
$stuecklisten = $data[6];
$freifelderuebersetzung = $data[7];
$this->app->DB->MysqlCopyRow('artikel','id',$id);
$idnew = $this->app->DB->GetInsertID();
$steuersatz = $this->app->DB->Select("SELECT steuersatz FROM artikel WHERE id = '$id' LIMIT 1");
if($steuersatz == ''){
$steuersatz = -1.00;
$this->app->DB->Update("UPDATE artikel SET steuersatz = '$steuersatz' WHERE id = '$idnew' LIMIT 1");
}
$this->app->DB->Update("UPDATE artikel SET nummer='' WHERE id='$idnew' LIMIT 1");
if($this->app->DB->Select("SELECT variante_kopie FROM artikel WHERE id = '$id' LIMIT 1"))$this->app->DB->Update("UPDATE artikel SET variante = 1, variante_von = '$id' WHERE id = '$idnew' LIMIT 1");
if($stuecklisten == 1){
// wenn stueckliste
$stueckliste = $this->app->DB->Select("SELECT stueckliste FROM artikel WHERE id='$id' LIMIT 1");
if($stueckliste==1)
{
$artikelarr = $this->app->DB->SelectArr("SELECT * FROM stueckliste WHERE stuecklistevonartikel='$id'");
$cartikelarr = $artikelarr?count($artikelarr):0;
for($i=0;$i<$cartikelarr;$i++)
{
$sort = $artikelarr[$i]['sort'];
$artikel = $artikelarr[$i]['artikel'];
$referenz = $artikelarr[$i]['referenz'];
$place = $artikelarr[$i]['place'];
$layer = $artikelarr[$i]['layer'];
$stuecklistevonartikel = $idnew;
$menge = $artikelarr[$i]['menge'];
$firma = $artikelarr[$i]['firma'];
$this->app->DB->Insert("INSERT INTO stueckliste (id,sort,artikel,referenz,place,layer,stuecklistevonartikel,menge,firma) VALUES
('','$sort','$artikel','$referenz','$place','$layer','$stuecklistevonartikel','$menge','$firma')");
}
}
}
/*$arbeitsanweisungen = $this->app->DB->SelectArr("SELECT id FROM `artikel_arbeitsanweisung` WHERE artikel = '$id'");
if($arbeitsanweisungen)
{
foreach($arbeitsanweisungen as $arbeitsanweisung)
{
$newarbeitsanweisung = $this->app->DB->MysqlCopyRow('artikel_arbeitsanweisung', 'id', $arbeitsanweisung['id']);
$this->app->DB->Update("UPDATE `artikel_arbeitsanweisung` SET artikel = '$idnew' WHERE id = '$newarbeitsanweisung' LIMIT 1");
}
}*/
//TODO hinweis es wuren keine Preise kopiert
if($einkaufspreise == 1){
$einkaufspreise = $this->app->DB->SelectArr("SELECT id FROM einkaufspreise WHERE artikel = '$id'");
if($einkaufspreise){
foreach($einkaufspreise as $preis){
$neuereinkaufspreis = $this->app->DB->MysqlCopyRow("einkaufspreise", "id", $preis['id']);
$this->app->DB->Update("UPDATE einkaufspreise SET artikel = '$idnew' WHERE id = '$neuereinkaufspreis' LIMIT 1");
}
}
}
if($verkaufspreise == 1){
$verkaufspreise = $this->app->DB->SelectArr("SELECT id FROM verkaufspreise WHERE artikel = '$id'");
if($verkaufspreise){
foreach($verkaufspreise as $preis){
$neuerverkaufspreis = $this->app->DB->MysqlCopyRow("verkaufspreise", "id", $preis['id']);
$this->app->DB->Update("UPDATE verkaufspreise SET artikel = '$idnew' WHERE id = '$neuerverkaufspreis' LIMIT 1");
}
}
}
if($dateien == 1){
$dateien = $this->app->DB->SelectArr("SELECT DISTINCT datei FROM datei_stichwoerter WHERE parameter = '$id' AND objekt = 'Artikel'");
$datei_stichwoerter = $this->app->DB->SelectArr("SELECT id,datei FROM datei_stichwoerter WHERE parameter = '$id' AND objekt = 'Artikel'");
if($dateien){
foreach($dateien as $datei){
$titel = $this->app->DB->Select("SELECT titel FROM datei WHERE id='".$datei['datei']."' LIMIT 1");
$beschreibung = $this->app->DB->Select("SELECT beschreibung FROM datei WHERE id='".$datei['datei']."' LIMIT 1");
$nummer = $this->app->DB->Select("SELECT nummer FROM datei WHERE id='".$datei['datei']."' LIMIT 1");
$name = $this->app->DB->Select("SELECT dateiname FROM datei_version WHERE datei='".$this->app->DB->real_escape_string($datei['datei'])."' ORDER by version DESC LIMIT 1");
$ersteller = $this->app->User->GetName();
$tmpnewdateiid = $this->app->erp->CreateDatei($name,$titel,$beschreibung,$nummer,$this->app->erp->GetDateiPfad($datei['datei']),$ersteller);
$datei_mapping[$datei['datei']] = $tmpnewdateiid;
}
}
if($datei_stichwoerter){
foreach($datei_stichwoerter as $datei){
$neuesstichwort = $this->app->DB->MysqlCopyRow("datei_stichwoerter", "id", $datei['id']);
$newdatei = $datei_mapping[$datei['datei']];
$this->app->DB->Update("UPDATE datei_stichwoerter SET datei='$newdatei', parameter = '$idnew', objekt = 'Artikel' WHERE id = '$neuesstichwort' LIMIT 1");
}
}
}
if($eigenschaften == 1){
$aeigenschaften = $this->app->DB->SelectArr("SELECT id FROM artikeleigenschaftenwerte WHERE artikel = '$id'");
if($aeigenschaften){
foreach($aeigenschaften as $eigenschaft){
$neue_eigenschaft = $this->app->DB->MysqlCopyRow("artikeleigenschaftenwerte", "id", $eigenschaft['id']);
$this->app->DB->Update("UPDATE artikeleigenschaftenwerte SET artikel = '$idnew' WHERE id = '$neue_eigenschaft' LIMIT 1");
}
}
}
//WERDEN AUCH SCHON IMMER KOPIERT
if($anweisungen == 1){
$arbeitsanweisungen = $this->app->DB->SelectArr("SELECT id FROM artikel_arbeitsanweisung WHERE artikel = '$id'");
if($arbeitsanweisungen){
foreach($arbeitsanweisungen as $anweisung){
$neue_anweisung = $this->app->DB->MysqlCopyRow("artikel_arbeitsanweisung", "id", $anweisung['id']);
$this->app->DB->Update("UPDATE artikel_arbeitsanweisung SET artikel = '$idnew' WHERE id = '$neue_anweisung' LIMIT 1");
}
}
}
if($freifelderuebersetzung == 1){
$freifelderuebersetzungen = $this->app->DB->SelectArr("SELECT id FROM artikel_freifelder WHERE artikel = '$id'");
if($freifelderuebersetzungen){
$this->app->DB->Insert("INSERT INTO artikel_freifelder (artikel, sprache, nummer, wert) SELECT '$idnew', sprache, nummer, wert FROM artikel_freifelder WHERE artikel = '$id'");
}
}
// artikelbilder kopieren
if($return){
return $idnew;
}
// eventuell einkaufspreise verkaufspreise und stueckliste kopieren?
$msg = $this->app->erp->base64_url_encode("<div class=error>Sie befinden sich in der neuen Kopie des Artikels. Bitte legen Sie Verkaufs- und Einkaufspreise und Bilder bzw. Dateien an! Diese wurden nicht kopiert!</div>");
$this->app->Location->execute("index.php?module=artikel&action=edit&msg=$msg&id=".$idnew);
}
public function ArtikelProjekte()
{
$this->app->Tpl->Add('UEBERSCHRIFT',' (Projekte)');

View File

@ -44,7 +44,7 @@ SPDX-License-Identifier: LicenseRef-EGPL-3.1
<fieldset>
<legend>{|Aktionen|}</legend>
<input type="button" class="btnGreenNew vueAction" data-action="variantEdit" data-article-id="[ID]" value="&#10010; Neue Variante">
<!--<input type="button" class="btnGreenNew vueAction" data-action="createMissing" data-article-id="[ID]" value="&#10010; Erzeuge fehlende Varianten">-->
<input type="button" class="btnGreenNew vueAction" data-action="createMissing" data-article-id="[ID]" value="&#10010; Erzeuge fehlende Varianten">
</fieldset>
</div>
</div>

View File

@ -7,6 +7,7 @@
use Xentral\Components\Http\JsonResponse;
use Xentral\Components\Http\Request;
use Xentral\Components\Http\Response;
use Xentral\Modules\Article\Service\ArticleService;
use Xentral\Modules\MatrixProduct\Data\Group;
use Xentral\Modules\MatrixProduct\Data\Option;
use Xentral\Modules\MatrixProduct\Data\Translation;
@ -16,6 +17,7 @@ class Matrixprodukt
{
private ApplicationCore $app;
private MatrixProductService $service;
private ArticleService $articleService;
private Request $request;
const MODULE_NAME = 'MatrixProduct';
@ -30,6 +32,7 @@ class Matrixprodukt
return;
$this->service = $this->app->Container->get('MatrixProductService');
$this->request = $this->app->Container->get('Request');
$this->articleService = $this->app->Container->get('ArticleService');
$this->app->ActionHandlerInit($this);
$this->app->ActionHandler("list", "ActionList");
@ -120,18 +123,13 @@ class Matrixprodukt
$heading[] = 'Artikel';
$width[] = '5%';
$nameColumns = [];
$optIdColumns = [];
$optNameColumns = [];
$optFrom = [];
$optWhere = [];
$joins = [];
foreach ($groups as $groupId => $groupName) {
$heading[] = $groupName;
$width[] = '5%';
$nameColumns[] = "name_$groupId";
$optIdColumns[] = "moa_$groupId.id";
$optNameColumns[] = "moa_$groupId.name as name_$groupId";
$optFrom[] = "matrixprodukt_eigenschaftenoptionen_artikel moa_$groupId";
$optWhere[] = "moa_$groupId.artikel = $id AND moa_$groupId.gruppe = $groupId";
$nameColumns[] = "MAX(moa_$groupId.name)";
$joins[] = "LEFT JOIN matrixprodukt_eigenschaftenoptionen_artikel moa_$groupId
ON mota.option_id=moa_$groupId.id AND moa_$groupId.gruppe = $groupId";
}
$heading[] = 'Men&uuml;';
$width[] = '1%';
@ -141,24 +139,15 @@ class Matrixprodukt
. "<img class=\"vueAction\" data-action=\"variantEdit\" data-variant-id=\"%value%\" data-article-id=\"$id\" src=\"./themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.svg\">&nbsp;"
. "<img class=\"vueAction\" data-action=\"variantDelete\" data-variant-id=\"%value%\" data-article-id=\"$id\" src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\">"
. "</td></tr></table>";
$optsqlIdCols = join(',', $optIdColumns);
$optsqlNameCols = join(',', $optNameColumns);
$optsqlFrom = join(' JOIN ', $optFrom);
$optsqlWhere = join(' AND ', $optWhere);
$optsql = "SELECT CONCAT_WS(',', $optsqlIdCols) idlist, $optsqlNameCols
FROM $optsqlFrom WHERE $optsqlWhere";
$artsql = "SELECT a.id, a.nummer, group_concat(mota.option_id order by mota.option_id separator ',') idlist
FROM matrixprodukt_optionen_zu_artikel mota
JOIN artikel a ON mota.artikel = a.id WHERE a.variante_von = $id group by mota.artikel";
$sqlNameCols = join(',', array_merge(['art.id', 'art.nummer'], $nameColumns, ['art.id']));
$sql = "SELECT SQL_CALC_FOUND_ROWS $sqlNameCols
FROM ($artsql) art ";
if (!empty($optsqlIdCols))
$sql .= " LEFT OUTER JOIN ($optsql) opts ON opts.idlist = art.idlist";
$where = "1";
//$count = "SELECT count(DISTINCT moa.id)
// FROM matrixprodukt_eigenschaftengruppen_artikel mga
// LEFT OUTER JOIN matrixprodukt_eigenschaftenoptionen_artikel moa on moa.gruppe = mga.id WHERE $where";
$joinSql = join("\n", $joins);
$sql = "SELECT SQL_CALC_FOUND_ROWS $sqlNameCols
FROM artikel art
LEFT JOIN matrixprodukt_optionen_zu_artikel mota ON mota.artikel = art.id
$joinSql";
$where = "art.variante_von = $id";
$groupby = "GROUP BY art.id";
$count = "SELECT count(*) FROM artikel art WHERE $where";
break;
case "matrixproduct_group_translations":
$heading = array('Name', 'Name (extern)', 'Sprache', 'Übersetzung Name', 'Übersetzung Name (extern)', 'Men&uuml;');
@ -357,10 +346,51 @@ class Matrixprodukt
$json = $this->request->getJson();
$this->service->DeleteVariant($json->variantId);
return JsonResponse::NoContent();
case "acarticles":
$query = $this->app->Secure->GetGET('query');
$result = $this->app->DB->SelectArr("SELECT id, nummer, name_de FROM artikel WHERE (nummer LIKE '%$query%' OR name_de LIKE '%$query%') AND geloescht = 0");
return new JsonResponse($result);
case "createMissing":
if ($this->request->getMethod() === 'GET') {
$articleId = $this->request->get->getInt('articleId');
$groups = $this->service->GetArticleGroupsByArticleId($articleId);
$options = $this->service->GetArticleOptionsByArticleId($articleId);
foreach ($groups as $group) {
$result[$group->id] = [
'name' => $group->name,
'selected' => [],
'required' => $group->required,
'options' => []
];
}
foreach ($options as $option) {
$result[$option->groupId]['options'][] = ['value' => $option->id, 'name' => $option->name];
$result[$option->groupId]['selected'][] = $option->id;
}
return new JsonResponse(['groups' => $result ?? []]);
} else {
$json = $this->request->getJson();
$list = [[]];
foreach ($json->groups as $group) {
if (empty($group->selected))
continue;
$newList = [];
foreach ($list as $old) {
foreach ($group->selected as $option) {
$newList[] = array_merge($old, [$option]);
}
}
$list = $newList;
}
$oldnumber = $this->app->DB->Select("SELECT nummer FROM artikel WHERE id = $json->articleId");
$created = [];
foreach ($list as $optionSet) {
$variantId = $this->service->GetVariantIdByOptionSet($optionSet);
if ($variantId)
continue;
$number = $oldnumber.'_'.$this->service->GetSuffixStringForOptionSet($optionSet);
$newId = $this->articleService->CopyArticle($json->articleId, true, true, true, true, true, true, true, $number);
$this->service->SaveVariant($json->articleId, $newId, $optionSet);
$created[] = $number;
}
return new JsonResponse($created);
}
}
$articleId = $this->app->Secure->GetGET('id');