Files
shopPRO/admin/templates/shop-product/product-combination.php
Jacek Pyziak 69e78ca248 ver. 0.294: Remove all 12 legacy autoload/shop/ classes (~2363 lines)
Complete Domain-Driven Architecture migration:
- Phase 1-4: Transport, ProductSet, Coupon, Shop, Search, Basket,
  ProductCustomField, Category, ProductAttribute, Promotion
- Phase 5: Order (~562 lines) + Product (~952 lines)
- ~20 Product methods migrated to ProductRepository
- Apilo sync migrated to OrderAdminService
- Production hotfixes: stale Redis cache (prices 0.00), unqualified
  Product:: refs in LayoutEngine, object->array template conversion
- AttributeRepository::getAttributeValueById() Redis cache added

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 02:05:39 +01:00

233 lines
9.4 KiB
PHP

<div class="g-container" data="table:order-details">
<div class="panel panel-info panel-border top">
<div class="panel-heading">
<span class="panel-title">Kombinacje produktu: <?= $this -> product['languages'][ $this -> default_language ]['name'];?></span>
</div>
<div class="panel-heading p10 pl15" id="g-menu" style="height: auto;">
<a class="btn btn btn-dark btn-sm mr5 btn-sm mr5" href="/admin/shop_product/view_list/"><i class="fa fa-reply mr5"></i>Wstecz</a>
</div>
<div class="panel-body">
<div class="row">
<div class="col-lg-7 col-xl-9">
<div class="table-responsive">
<table class="table table-hover table-bordered table-condensed">
<thead>
<tr>
<th>Kombinacja</th>
<th>SKU</th>
<th>Stan magazynowy</th>
<th>Cena netto</th>
<th>Zam. przy braku</th>
<th style="width: 100px;">Opcje</th>
</tr>
</thead>
<tbody>
<? if ( \Shared\Helpers\Helpers::is_array_fix( $this -> product_permutations ) ): foreach ( $this -> product_permutations as $product ):?>
<tr data-combination-id="<?= $product['id'];?>">
<td>
<?
$attributes = explode( '|', $product['permutation_hash'] );
foreach ( $attributes as $attribute ):
$attribute_tmp = explode( '-', $attribute );
$attrRepo = new \Domain\Attribute\AttributeRepository( $GLOBALS['mdb'] );
echo $attrRepo->getAttributeNameById( (int)$attribute_tmp[0], $this -> default_language ) . ' - <b>' . $attrRepo->getAttributeValueById( (int)$attribute_tmp[1], $this -> default_language ) . '</b>';
if ( $attribute != end( $attributes ) )
echo ', ';
endforeach;
?>
</td>
<td>
<input type="text" value="<?= $product['sku'];?>" class="form-control combination-field" style="max-width: 100px;" data-product-id="<?= $product['id'];?>" data-field="sku">
</td>
<td>
<input type="text" value="<?= $product['quantity'];?>" class="form-control combination-field" style="max-width: 100px;" data-product-id="<?= $product['id'];?>" data-field="quantity">
</td>
<td>
<input type="text" value="<?= $product['price_netto'];?>" class="form-control combination-field" style="max-width: 100px;" data-product-id="<?= $product['id'];?>" data-field="price">
</td>
<td>
<input type="checkbox" class="g-checkbox combination-checkbox" data-product-id="<?= $product['id'];?>" <? if ( $product['stock_0_buy'] ): echo 'checked="checked"'; endif;?>>
</td>
<td class="text-center">
<button type="button" class="btn btn-danger btn-delete-permutation" data-combination-id="<?= $product['id'];?>"><i class="fa fa-trash"></i></button>
</td>
</tr>
<? endforeach; endif;?>
</tbody>
</table>
</div>
</div>
<div class="col-lg-5 col-xl-3">
<form action="/admin/shop_product/generate_combination/product_id=<?= $this -> product['id'];?>" method="POST">
<button type="submit" class="btn btn-success" style="margin-bottom: 25px;">Wygeneruj kombinacje</button>
<? foreach ( $this -> attributes as $attribute ):?>
<div class="combination-attribute">
<div class="title">
<?= $attribute['languages'][ $this -> default_language ]['name'];?>
<label style="float: right; font-weight: normal; font-size: 12px; cursor: pointer;"><input type="checkbox" class="g-checkbox select-all-attr"> wszystkie</label>
</div>
<ul class="values">
<? foreach ( $attribute['values'] as $value ):?>
<li>
<input type="checkbox" class="g-checkbox" name="attribute_<?= $attribute['id'];?>[]" value="<?= $value['id'];?>"> <?= $value['languages'][ $this -> default_language ]['name'];?>
</li>
<? endforeach;?>
</ul>
</div>
<? endforeach;?>
</form>
</div>
</div>
</div>
</div>
</div>
<link rel="stylesheet" type="text/css" href="/libraries/grid/plugins/icheck/skins/minimal/minimal.css">
<link rel="stylesheet" type="text/css" href="/libraries/grid/plugins/icheck/skins/minimal/blue.css">
<script type="text/javascript" src="/libraries/grid/plugins/icheck/icheck.min.js"></script>
<script type="text/javascript">
$( function()
{
$( '.g-checkbox, .g-radio' ).iCheck({
checkboxClass: 'icheckbox_minimal-blue',
radioClass: 'iradio_minimal-blue'
});
// "Zaznacz wszystkie" per atrybut
$( '.select-all-attr' ).on( 'ifChanged', function()
{
var checked = $( this ).is( ':checked' );
$( this ).closest( '.combination-attribute' ).find( '.g-checkbox' ).each( function()
{
$( this ).iCheck( checked ? 'check' : 'uncheck' );
});
});
// Inline save — SKU, ilość, cena
var fieldUrlMap = {
'sku': '/admin/shop_product/product_combination_sku_save/',
'quantity': '/admin/shop_product/product_combination_quantity_save/',
'price': '/admin/shop_product/product_combination_price_save/'
};
$( 'body' ).on( 'change', '.combination-field', function()
{
var $input = $( this );
var field = $input.data( 'field' );
var data = { product_id: $input.data( 'product-id' ) };
data[ field ] = $input.val();
$.ajax({
type: 'POST',
cache: false,
url: fieldUrlMap[ field ],
data: data,
beforeSend: function() {
$( '#overlay' ).show();
},
success: function( data ) {
$( '#overlay' ).hide();
var response = jQuery.parseJSON( data );
if ( response.status === 'ok' ) {
$input.css( 'border-color', '#1cbb8c' );
setTimeout( function() { $input.css( 'border-color', '' ); }, 1500 );
} else {
$input.css( 'border-color', '#ff3d60' );
setTimeout( function() { $input.css( 'border-color', '' ); }, 1500 );
if ( response.msg ) create_error( response.msg );
}
},
error: function() {
$( '#overlay' ).hide();
$input.css( 'border-color', '#ff3d60' );
setTimeout( function() { $input.css( 'border-color', '' ); }, 1500 );
}
});
});
// Inline save — checkbox stock_0_buy (iCheck event)
$( 'body' ).on( 'ifChanged', '.combination-checkbox', function()
{
var $cb = $( this );
$.ajax({
type: 'POST',
cache: false,
url: '/admin/shop_product/product_combination_stock_0_buy_save/',
data: { product_id: $cb.data( 'product-id' ), stock_0_buy: $cb.is( ':checked' ) },
beforeSend: function() {
$( '#overlay' ).show();
},
success: function( data ) {
$( '#overlay' ).hide();
var response = jQuery.parseJSON( data );
if ( response.status !== 'ok' && response.msg ) {
create_error( response.msg );
}
},
error: function() {
$( '#overlay' ).hide();
}
});
});
// Usuwanie kombinacji — AJAX
$( 'body' ).on( 'click', '.btn-delete-permutation', function(e)
{
e.preventDefault();
var combinationId = $( this ).data( 'combination-id' );
var $row = $( this ).closest( 'tr' );
$.alert(
{
title: 'Pytanie',
content: 'Na pewno chcesz usunąć wybraną kombinację?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
},
confirm: {
text: 'Tak',
btnClass: 'btn-danger',
keys: ['enter'],
action: function()
{
$.ajax({
type: 'POST',
cache: false,
url: '/admin/shop_product/delete_combination_ajax/',
data: { combination_id: combinationId },
beforeSend: function() {
$( '#overlay' ).show();
},
success: function( data ) {
$( '#overlay' ).hide();
var response = jQuery.parseJSON( data );
if ( response.status === 'ok' ) {
$row.fadeOut( 300, function() { $( this ).remove(); } );
} else {
if ( response.msg ) create_error( response.msg );
}
},
error: function() {
$( '#overlay' ).hide();
}
});
}
}
}
});
});
});
</script>