diff --git a/admin/templates/articles/article-edit-custom-script.php b/admin/templates/articles/article-edit-custom-script.php index 964f801..92e5169 100644 --- a/admin/templates/articles/article-edit-custom-script.php +++ b/admin/templates/articles/article-edit-custom-script.php @@ -52,6 +52,49 @@ if (!empty($_COOKIE['cookie_menus'])) { + + + + +
Masowa edycja produktów
@@ -8,7 +60,7 @@
- +
@@ -24,200 +76,39 @@
- products as $key => $product ):?> -
- - + products ) ): foreach ( $this->products as $key => $product ): ?> +
+ +
- +
- - \ No newline at end of file + diff --git a/admin/templates/shop-product/subcategories-list.php b/admin/templates/shop-product/subcategories-list.php index 80bece4..9037323 100644 --- a/admin/templates/shop-product/subcategories-list.php +++ b/admin/templates/shop-product/subcategories-list.php @@ -3,7 +3,9 @@ categories as $category ):?>
  • - + ';?> product_categories ) and in_array( $category[ 'id' ], $this -> product_categories ) ):?>checked="checked" /> dlang ][ 'title' ];?> diff --git a/autoload/Domain/Product/ProductRepository.php b/autoload/Domain/Product/ProductRepository.php index e397697..bb83ecf 100644 --- a/autoload/Domain/Product/ProductRepository.php +++ b/autoload/Domain/Product/ProductRepository.php @@ -244,4 +244,157 @@ class ProductRepository return true; } + + /** + * Pobiera listę wszystkich produktów głównych (id => name) do masowej edycji. + * Zwraca tylko produkty bez parent_id (bez kombinacji). + * + * @return array Mapa id => nazwa produktu + */ + public function allProductsForMassEdit(): array + { + $defaultLang = $this->db->get( 'pp_langs', 'id', [ 'start' => 1 ] ); + if ( !$defaultLang ) { + $defaultLang = 'pl'; + } + + $results = $this->db->select( 'pp_shop_products', 'id', [ 'parent_id' => null ] ); + $products = []; + + if ( is_array( $results ) ) { + foreach ( $results as $id ) { + $name = $this->db->get( 'pp_shop_products_langs', 'name', [ + 'AND' => [ 'product_id' => $id, 'lang_id' => $defaultLang ] + ] ); + $products[ (int) $id ] = $name ?: ''; + } + } + + return $products; + } + + /** + * Pobiera listę ID produktów przypisanych do danej kategorii. + * + * @param int $categoryId ID kategorii + * @return int[] Lista ID produktów + */ + public function getProductsByCategory(int $categoryId): array + { + $results = $this->db->select( + 'pp_shop_products_categories', + 'product_id', + [ 'category_id' => $categoryId ] + ); + + return is_array( $results ) ? $results : []; + } + + /** + * Aplikuje rabat procentowy na produkt (cena promocyjna = cena - X%). + * Aktualizuje również ceny kombinacji produktu. + * + * @param int $productId ID produktu + * @param float $discountPercent Procent rabatu + * @return array|null Tablica z price_brutto i price_brutto_promo lub null przy błędzie + */ + public function applyDiscountPercent(int $productId, float $discountPercent): ?array + { + $product = $this->db->get( 'pp_shop_products', [ + 'vat', 'price_brutto', 'price_netto' + ], [ 'id' => $productId ] ); + + if ( !$product ) { + return null; + } + + $vat = $product['vat']; + $priceBrutto = (float) $product['price_brutto']; + $priceNetto = (float) $product['price_netto']; + + $priceBruttoPromo = $priceBrutto - ( $priceBrutto * ( $discountPercent / 100 ) ); + $priceNettoPromo = $priceNetto - ( $priceNetto * ( $discountPercent / 100 ) ); + + if ( $priceBrutto == $priceBruttoPromo ) { + $priceBruttoPromo = null; + } + if ( $priceNetto == $priceNettoPromo ) { + $priceNettoPromo = null; + } + + $this->db->update( 'pp_shop_products', [ + 'price_brutto_promo' => $priceBruttoPromo, + 'price_netto_promo' => $priceNettoPromo + ], [ 'id' => $productId ] ); + + $this->updateCombinationPrices( $productId, $priceNetto, $vat, $priceNettoPromo ); + + return [ + 'price_brutto' => $priceBrutto, + 'price_brutto_promo' => $priceBruttoPromo + ]; + } + + /** + * Aktualizuje ceny kombinacji produktu uwzględniając wpływ na cenę (impact_on_the_price). + * + * @param int $productId ID produktu nadrzędnego + * @param float $priceNetto Cena netto bazowa + * @param float $vat Stawka VAT + * @param float|null $priceNettoPromo Cena promo netto bazowa (null = brak) + */ + private function updateCombinationPrices(int $productId, float $priceNetto, float $vat, ?float $priceNettoPromo): void + { + $priceBrutto = \S::normalize_decimal( $priceNetto * ( 100 + $vat ) / 100, 2 ); + $priceBruttoPromo = $priceNettoPromo !== null + ? \S::normalize_decimal( $priceNettoPromo * ( 100 + $vat ) / 100, 2 ) + : null; + + $combinations = $this->db->query( + 'SELECT psp.id ' + . 'FROM pp_shop_products AS psp ' + . 'INNER JOIN pp_shop_products_attributes AS pspa ON psp.id = pspa.product_id ' + . 'INNER JOIN pp_shop_attributes_values AS psav ON pspa.value_id = psav.id ' + . 'WHERE psav.impact_on_the_price > 0 AND psp.parent_id = :product_id', + [ ':product_id' => $productId ] + ); + + if ( !$combinations ) { + return; + } + + $rows = $combinations->fetchAll( \PDO::FETCH_ASSOC ); + foreach ( $rows as $row ) { + $combBrutto = $priceBrutto; + $combBruttoPromo = $priceBruttoPromo; + + $values = $this->db->query( + 'SELECT impact_on_the_price FROM pp_shop_attributes_values AS psav ' + . 'INNER JOIN pp_shop_products_attributes AS pspa ON pspa.value_id = psav.id ' + . 'WHERE impact_on_the_price IS NOT NULL AND product_id = :product_id', + [ ':product_id' => $row['id'] ] + ); + + if ( $values ) { + foreach ( $values->fetchAll( \PDO::FETCH_ASSOC ) as $value ) { + $combBrutto += $value['impact_on_the_price']; + if ( $combBruttoPromo !== null ) { + $combBruttoPromo += $value['impact_on_the_price']; + } + } + } + + $combNetto = \S::normalize_decimal( $combBrutto / ( 100 + $vat ) * 100, 2 ); + $combNettoPromo = $combBruttoPromo !== null + ? \S::normalize_decimal( $combBruttoPromo / ( 100 + $vat ) * 100, 2 ) + : null; + + $this->db->update( 'pp_shop_products', [ + 'price_netto' => $combNetto, + 'price_brutto' => $combBrutto, + 'price_netto_promo' => $combNettoPromo, + 'price_brutto_promo' => $combBruttoPromo + ], [ 'id' => $row['id'] ] ); + } + } } diff --git a/autoload/admin/Controllers/ArticlesController.php b/autoload/admin/Controllers/ArticlesController.php index b9bccf2..7606ddd 100644 --- a/autoload/admin/Controllers/ArticlesController.php +++ b/autoload/admin/Controllers/ArticlesController.php @@ -440,7 +440,9 @@ class ArticlesController $html .= '
      '; $html .= '