- Order product CRUD in admin panel (add, delete, edit quantity/prices) - AJAX product search endpoint for order edit form - Automatic stock adjustment when editing order products - Transport cost recalculation based on free delivery threshold - Fix: promo price = 0 when equal to base price (no real promotion) - Clean up stale temp/ build artifacts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
266 lines
13 KiB
PHP
266 lines
13 KiB
PHP
<?
|
|
$orderId = (int)($this -> order['id'] ?? 0);
|
|
?>
|
|
|
|
<div class="site-title">Edycja zamówienia: <?= htmlspecialchars((string)($this -> order['number'] ?? ''), ENT_QUOTES, 'UTF-8');?></div>
|
|
|
|
<div class="mb15">
|
|
<button type="button" id="order-save" class="btn btn-success btn-sm mr5 ml5">
|
|
<i class="fa fa-save"></i> Zapisz zamówienie
|
|
</button>
|
|
<a href="/admin/shop_order/order_details/order_id=<?= $orderId;?>" class="btn btn-dark btn-sm mr5">
|
|
<i class="fa fa-reply"></i> Wstecz
|
|
</a>
|
|
</div>
|
|
|
|
<form id="fg-order-details" method="POST" action="/admin/shop_order/order_save/">
|
|
<input type="hidden" name="order_id" value="<?= $orderId;?>">
|
|
<div class="details panel">
|
|
<div class="panel-body">
|
|
<div class="row">
|
|
<div class="col-xl-8">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="text-big">Numer zamówienia: <b id="order-number"><?= $this -> order[ 'number' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-number' ); return false;"></i></div>
|
|
<div>Data zamówienia <b><?= $this -> order[ 'date_order' ];?></b></div>
|
|
<br>
|
|
<div class="text-big">Dane do dostawy:</div>
|
|
<div class="row">
|
|
<div class="col-sm-6">
|
|
<input type="text" class="form-control" name="client_name" value="<?= $this -> order[ 'client_name' ];?>" placeholder="Imię">
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<input type="text" class="form-control" name="client_surname" value="<?= $this -> order[ 'client_surname' ];?>" placeholder="Nazwisko">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<input type="text" class="form-control" name="client_street" value="<?= $this -> order[ 'client_street' ];?>" placeholder="Ulica">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-6">
|
|
<input type="text" class="form-control" name="client_postal_code" value="<?= $this -> order[ 'client_postal_code' ];?>" placeholder="Kod pocztowy">
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<input type="text" class="form-control" name="client_city" value="<?= $this -> order[ 'client_city' ];?>" placeholder="Miasto">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<input type="text" class="form-control" name="client_email" value="<?= $this -> order[ 'client_email' ];?>" placeholder="Email">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<input type="text" class="form-control" name="client_phone" value="<?= $this -> order[ 'client_phone' ];?>" placeholder="Telefon">
|
|
</div>
|
|
</div>
|
|
<? if ( $this -> order['firm_name'] ):?>
|
|
<div class="text-big">Dane do faktury:</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<input type="text" class="form-control" name="firm_name" value="<?= $this -> order[ 'firm_name' ];?>" placeholder="Nazwa firmy">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<input type="text" class="form-control" name="firm_street" value="<?= $this -> order[ 'firm_street' ];?>" placeholder="Ulica">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-6">
|
|
<input type="text" class="form-control" name="firm_postal_code" value="<?= $this -> order[ 'firm_postal_code' ];?>" placeholder="Kod pocztowy">
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<input type="text" class="form-control" name="firm_city" value="<?= $this -> order[ 'firm_city' ];?>" placeholder="Miasto">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<input type="text" class="form-control" name="firm_nip" value="<?= $this -> order[ 'firm_nip' ];?>" placeholder="NIP">
|
|
</div>
|
|
</div>
|
|
<? endif;?>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div>Kwota zamówienia <b id="order-summary-display"><?= $this -> order[ 'summary' ];?> zł</b></div>
|
|
<div class="mt5">
|
|
<span>Produkty: <b id="products-total-display">0,00</b> zł</span>
|
|
|
|
|
<span>Dostawa: <b id="transport-cost-display"><?= number_format((float)($this -> order['transport_cost'] ?? 0), 2, ',', '');?></b> zł</span>
|
|
</div>
|
|
<br>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<select name="transport_id" class="form-control" id="transport_id">
|
|
<option value="0">--- wybierz formę transportu ---</option>
|
|
<? if ( \Shared\Helpers\Helpers::is_array_fix( $this -> transport ) ): foreach ( $this -> transport as $transport_tmp ):?>
|
|
<option value="<?= $transport_tmp['id'];?>" <? if ( $this -> order['transport_id'] == $transport_tmp['id'] ):?>selected="selected"<? endif;?>>
|
|
<?= $transport_tmp['name'];?> - <?= $transport_tmp['cost'];?> zł
|
|
</option>
|
|
<? endforeach; endif;?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="row row-flex">
|
|
<div class="col-12">
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" name="inpost_paczkomat" id="inpost_paczkomat" value="<?= $this -> order[ 'inpost_paczkomat' ];?>" placeholder="Paczkomat">
|
|
<span class="input-group-addon btn btn-danger btn-paczkomat">
|
|
<i class="fa fa-folder"></i>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<select name="payment_method_id" class="form-control" id="payment_method_id">
|
|
<option value="0">--- wybierz formę płatności ---</option>
|
|
<? if ( \Shared\Helpers\Helpers::is_array_fix( $this -> payment_methods ) ): foreach ( $this -> payment_methods as $payment_method ):?>
|
|
<option value="<?= $payment_method['id'];?>" <? if ( $this -> order['payment_method_id'] == $payment_method['id'] ):?>selected="selected"<? endif;?>>
|
|
<?= $payment_method['name'];?>
|
|
</option>
|
|
<? endforeach; endif;?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-4">
|
|
<div class="order-status text-big">
|
|
<?= $this -> order_statuses[ $this -> order[ 'status' ] ];?>
|
|
</div>
|
|
<div class="form-group status_select">
|
|
<select class="form-control" id="order-status">
|
|
<? foreach ( $this -> order_statuses as $key => $val ):?>
|
|
<option value="<?= $key;?>" <? if ( $key==$this -> order[ 'status' ] ):?>selected="selected"
|
|
<? endif;?>><?= $val;?>
|
|
</option>
|
|
<? endforeach;?>
|
|
</select>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12 buttons">
|
|
<button class="btn btn-primary order_status_change_email">zmień status i wyślij email</button>
|
|
<button class="btn btn-success order_status_change">zmień status</button>
|
|
</div>
|
|
<div class="col-12 order-history">
|
|
<? if ( \Shared\Helpers\Helpers::is_array_fix( $this -> order['statuses'] ) ): foreach ( $this -> order['statuses'] as $status ):?>
|
|
<div><b><?= date( 'Y-m-d H:i', strtotime( $status['date'] ) );?></b>: <?= $this -> order_statuses[$status['status_id']];?></div>
|
|
<? endforeach; endif;?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
</div>
|
|
<div class="col-md-4">
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="text-big">Wiadomość do zamówienia:</div>
|
|
<div> <b> <?= $this -> order[ 'message' ];?> </b></div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="text-big mb5">Produkty zamówienia:</div>
|
|
<div class="table-responsive">
|
|
<table class="table" id="order-products-table">
|
|
<thead>
|
|
<tr>
|
|
<th style="width:60px">Zdjęcie</th>
|
|
<th scope="col">Nazwa</th>
|
|
<th scope="col" class="tab-center" style="width:80px">Ilość</th>
|
|
<th scope="col" class="tab-right" style="width:130px">Cena / szt:</th>
|
|
<th scope="col" class="tab-right" style="width:130px">Cena promo:</th>
|
|
<th scope="col" class="tab-right" style="width:110px">Suma:</th>
|
|
<th scope="col" style="width:40px"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="order-products-body">
|
|
<? $productRepo = new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ); ?>
|
|
<? if ( is_array( $this -> order[ 'products' ] ) ): foreach ( $this -> order[ 'products' ] as $i => $product ):?>
|
|
<tr class="order-product-row" data-index="<?= $i;?>">
|
|
<input type="hidden" name="products[<?= $i;?>][order_product_id]" value="<?= (int)$product['id'];?>">
|
|
<input type="hidden" name="products[<?= $i;?>][product_id]" value="<?= (int)$product['product_id'];?>">
|
|
<input type="hidden" name="products[<?= $i;?>][parent_product_id]" value="<?= (int)($product['parent_product_id'] ?? $product['product_id']);?>">
|
|
<input type="hidden" name="products[<?= $i;?>][name]" value="<?= htmlspecialchars((string)$product['name'], ENT_QUOTES, 'UTF-8');?>">
|
|
<input type="hidden" name="products[<?= $i;?>][vat]" value="<?= (float)($product['vat'] ?? 0);?>">
|
|
<td class="product-image">
|
|
<? if ( $product['product_id'] ):?>
|
|
<img src="<?= $productRepo->getProductImg( (int)$product['product_id'] );?>" style="max-width:50px;max-height:50px;">
|
|
<? endif;?>
|
|
</td>
|
|
<td>
|
|
<a href="<?= $productRepo->getProductUrl( (int)$product['product_id'] );?>" target="_blank"><?= $product[ 'name' ];?></a>
|
|
<? if ( $product['attributes'] ):?>
|
|
<div class="atributes small text-muted"><?= $product[ 'attributes' ];?></div>
|
|
<? endif;?>
|
|
<? if ( $product[ 'message' ] != '' ):?>
|
|
<div class="product-message small"><strong>Wiadomość:</strong> <?= $product['message'];?></div>
|
|
<? endif;?>
|
|
</td>
|
|
<td class="tab-center">
|
|
<input type="number" name="products[<?= $i;?>][quantity]" value="<?= (int)$product['quantity'];?>" min="1" class="form-control form-control-sm text-center product-qty" style="width:70px">
|
|
</td>
|
|
<td class="tab-right">
|
|
<input type="number" name="products[<?= $i;?>][price_brutto]" value="<?= number_format((float)$product['price_brutto'], 2, '.', '');?>" step="0.01" min="0" class="form-control form-control-sm text-right product-price" style="width:110px">
|
|
</td>
|
|
<td class="tab-right">
|
|
<input type="number" name="products[<?= $i;?>][price_brutto_promo]" value="<?= number_format((float)$product['price_brutto_promo'], 2, '.', '');?>" step="0.01" min="0" class="form-control form-control-sm text-right product-price-promo" style="width:110px">
|
|
</td>
|
|
<td class="tab-right product-row-total">
|
|
<?= number_format(((float)$product['price_brutto_promo'] > 0 ? (float)$product['price_brutto_promo'] : (float)$product['price_brutto']) * (int)$product['quantity'], 2, ',', '');?> zł
|
|
</td>
|
|
<td class="text-center">
|
|
<button type="button" class="btn btn-xs btn-danger btn-remove-product" title="Usuń produkt"><i class="fa fa-times"></i></button>
|
|
</td>
|
|
</tr>
|
|
<? endforeach; endif;?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mb15" id="add-product-section">
|
|
<div class="text-big mb5">Dodaj produkt:</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div style="position:relative">
|
|
<input type="text" id="product-search-input" class="form-control" placeholder="Wpisz nazwę produktu..." autocomplete="off">
|
|
<div id="product-search-results" style="display:none;position:absolute;z-index:1000;width:100%;max-height:300px;overflow-y:auto;background:#fff;border:1px solid #ddd;border-top:none;box-shadow:0 2px 8px rgba(0,0,0,0.15)"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<form>
|
|
<div class="form-group">
|
|
<label for="note">Notatki</label>
|
|
<textarea class="form-control" id="note" rows="10"></textarea>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="inpost-map-container">
|
|
<a href="#" onclick="$( '.inpost-map-container' ).hide(); return false;" class="inpost-hide"><?= \Shared\Helpers\Helpers::lang( 'zamknij' );?></a>
|
|
<div id="inpost-map"></div>
|
|
</div>
|
|
<link class="footer" rel="stylesheet" type="text/css" href="https://geowidget.easypack24.net/css/easypack.css">
|
|
<script class="footer" type="text/javascript" src="https://geowidget.easypack24.net/js/sdk-for-javascript.js"></script>
|
|
<script type="text/javascript">
|
|
var orderEditConfig = {
|
|
transports: <?= $this -> transports_json ?? '[]';?>,
|
|
freeDelivery: <?= (float)($this -> free_delivery ?? 0);?>,
|
|
currentTransportCost: <?= (float)($this -> order['transport_cost'] ?? 0);?>
|
|
};
|
|
</script>
|
|
<?= \Shared\Tpl\Tpl::view('shop-order/order-edit-custom-script');?>
|