Kgshop commited on
Commit
9410089
·
verified ·
1 Parent(s): 6aac8d5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -48
app.py CHANGED
@@ -1200,7 +1200,6 @@ def item_movement_report():
1200
  html = BASE_TEMPLATE.replace('__TITLE__', "Движение товаров").replace('__CONTENT__', ITEM_MOVEMENT_CONTENT).replace('__SCRIPTS__', ITEM_MOVEMENT_SCRIPTS)
1201
  return render_template_string(html, inventory=inventory, movements=movements, product_id=product_id, variant_id=variant_id, selected_product=selected_product, selected_variant=selected_variant)
1202
 
1203
-
1204
  @app.route('/reports/product_roi')
1205
  @admin_required
1206
  def product_roi_report():
@@ -3197,9 +3196,7 @@ INVENTORY_CONTENT = """
3197
  <div id="modal-scanner-add" class="mb-2" style="display:none;"></div>
3198
  <hr>
3199
  <h6>Варианты товара</h6>
3200
- <div style="max-height: 40vh; overflow-y: auto; padding: 10px; border: 1px solid #dee2e6; border-radius: .25rem;" class="mb-2">
3201
- <div id="variants-container-add"></div>
3202
- </div>
3203
  <button type="button" class="btn btn-sm btn-outline-success mt-2" id="add-variant-btn-add">Добавить вариант</button>
3204
  </div>
3205
  <div class="modal-footer"><button type="submit" class="btn btn-primary">Сохранить</button></div>
@@ -3222,36 +3219,34 @@ INVENTORY_CONTENT = """
3222
  </div>
3223
  <hr>
3224
  <h6>Варианты товара</h6>
3225
- <div style="max-height: 40vh; overflow-y: auto; padding: 10px; border: 1px solid #dee2e6; border-radius: .25rem;" class="mb-2">
3226
- <div id="variants-container-edit-{{ p.id }}">
3227
- {% for v in p.variants %}
3228
- <div class="card mb-3 variant-row">
3229
- <div class="card-body">
3230
- <input type="hidden" name="variant_id[]" value="{{ v.id }}">
3231
- <div class="row g-2 align-items-center">
3232
- <div class="col-12 col-md-3">
3233
- <img src="{{ v.image_url if v.image_url else url_for('static', filename='placeholder.png') }}" class="img-thumbnail variant-preview mb-1" style="width: 80px; height: 80px; object-fit: cover;">
3234
- <input type="file" class="form-control form-control-sm variant-image-upload" accept="image/*">
3235
- <input type="hidden" class="variant-image-url-input" name="variant_image_url[]" value="{{ v.image_url }}">
3236
- </div>
3237
- <div class="col-12 col-md-9">
3238
- <div class="row g-2">
3239
- <div class="col-12"><label>Название варианта</label><input type="text" name="variant_name[]" class="form-control" value="{{ v.option_value }}" required></div>
3240
- <div class="col-12 col-sm-4"><label>Цена Общая</label><input type="text" name="variant_price_regular[]" class="form-control" value="{{ v.get('price_regular', v.get('price'))|string|replace('.', ',') }}" inputmode="decimal"></div>
3241
- <div class="col-12 col-sm-4"><label>Цена Мин.</label><input type="text" name="variant_price_min[]" class="form-control" value="{{ v.get('price_min', '0.00')|string|replace('.', ',') }}" inputmode="decimal"></div>
3242
- <div class="col-12 col-sm-4"><label>Цена Опт.</label><input type="text" name="variant_price_wholesale[]" class="form-control" value="{{ v.get('price_wholesale', '0.00')|string|replace('.', ',') }}" inputmode="decimal"></div>
3243
- <div class="col-12 col-sm-6"><label>Себестоимость</label><input type="text" name="variant_cost_price[]" class="form-control" value="{{ v.cost_price|string|replace('.', ',') }}" inputmode="decimal"></div>
3244
- <div class="col-12 col-sm-6"><label>Остаток</label><input type="number" name="variant_stock[]" class="form-control" value="{{ v.stock }}"></div>
3245
- </div>
3246
- </div>
3247
- <div class="col-12 text-end">
3248
- <button type="button" class="btn btn-sm btn-danger remove-variant-btn"><i class="fas fa-times"></i> Удалить вариант</button>
3249
- </div>
3250
- </div>
3251
- </div>
3252
- </div>
3253
- {% endfor %}
3254
  </div>
 
3255
  </div>
3256
  <button type="button" class="btn btn-sm btn-outline-success mt-2 add-variant-btn-edit" data-target-container="variants-container-edit-{{ p.id }}">Добавить вариант</button>
3257
  </div>
@@ -3359,7 +3354,7 @@ document.addEventListener('DOMContentLoaded', () => {
3359
  let currentScanner = null;
3360
  let currentScannerContainer = null;
3361
  const placeholderImg = "{{ url_for('static', filename='placeholder.png') }}";
3362
- const inventoryData = JSON.parse('{{ inventory|tojson|safe }}');
3363
  const isAdmin = {{ 'true' if session.admin_logged_in else 'false' }};
3364
 
3365
  function startScannerFor(containerId, inputElement, callback) {
@@ -3561,8 +3556,6 @@ document.addEventListener('DOMContentLoaded', () => {
3561
  </div>
3562
  </div>
3563
  `;
3564
- div.querySelector('.remove-variant-btn').addEventListener('click', () => div.remove());
3565
- div.querySelector('.variant-image-upload').addEventListener('change', (e) => handleImageUpload(e.target));
3566
  return div;
3567
  };
3568
 
@@ -3572,20 +3565,22 @@ document.addEventListener('DOMContentLoaded', () => {
3572
  }
3573
  });
3574
 
3575
- document.getElementById('add-variant-btn-add').addEventListener('click', () => {
3576
- document.getElementById('variants-container-add').appendChild(createVariantRow());
3577
- });
3578
-
3579
- document.querySelectorAll('.add-variant-btn-edit').forEach(btn => {
3580
- btn.addEventListener('click', (e) => {
3581
- const containerId = e.target.dataset.targetContainer;
3582
- document.getElementById(containerId).appendChild(createVariantRow());
3583
- });
3584
- });
3585
-
3586
  document.body.addEventListener('click', e => {
 
 
 
 
 
 
 
 
 
 
 
 
3587
  if (e.target.closest('.remove-variant-btn')) {
3588
  e.target.closest('.variant-row').remove();
 
3589
  }
3590
  });
3591
 
@@ -4069,7 +4064,7 @@ ITEM_MOVEMENT_CONTENT = """
4069
  ITEM_MOVEMENT_SCRIPTS = """
4070
  <script>
4071
  document.addEventListener('DOMContentLoaded', () => {
4072
- const inventoryData = JSON.parse('{{ inventory|tojson|safe }}');
4073
  const searchInput = document.getElementById('movement-search');
4074
  const searchResults = document.getElementById('movement-search-results');
4075
  const productIdInput = document.getElementById('movement-product-id');
 
1200
  html = BASE_TEMPLATE.replace('__TITLE__', "Движение товаров").replace('__CONTENT__', ITEM_MOVEMENT_CONTENT).replace('__SCRIPTS__', ITEM_MOVEMENT_SCRIPTS)
1201
  return render_template_string(html, inventory=inventory, movements=movements, product_id=product_id, variant_id=variant_id, selected_product=selected_product, selected_variant=selected_variant)
1202
 
 
1203
  @app.route('/reports/product_roi')
1204
  @admin_required
1205
  def product_roi_report():
 
3196
  <div id="modal-scanner-add" class="mb-2" style="display:none;"></div>
3197
  <hr>
3198
  <h6>Варианты товара</h6>
3199
+ <div id="variants-container-add"></div>
 
 
3200
  <button type="button" class="btn btn-sm btn-outline-success mt-2" id="add-variant-btn-add">Добавить вариант</button>
3201
  </div>
3202
  <div class="modal-footer"><button type="submit" class="btn btn-primary">Сохранить</button></div>
 
3219
  </div>
3220
  <hr>
3221
  <h6>Варианты товара</h6>
3222
+ <div id="variants-container-edit-{{ p.id }}">
3223
+ {% for v in p.variants %}
3224
+ <div class="card mb-3 variant-row">
3225
+ <div class="card-body">
3226
+ <input type="hidden" name="variant_id[]" value="{{ v.id }}">
3227
+ <div class="row g-2 align-items-center">
3228
+ <div class="col-12 col-md-3">
3229
+ <img src="{{ v.image_url if v.image_url else url_for('static', filename='placeholder.png') }}" class="img-thumbnail variant-preview mb-1" style="width: 80px; height: 80px; object-fit: cover;">
3230
+ <input type="file" class="form-control form-control-sm variant-image-upload" accept="image/*">
3231
+ <input type="hidden" class="variant-image-url-input" name="variant_image_url[]" value="{{ v.image_url }}">
3232
+ </div>
3233
+ <div class="col-12 col-md-9">
3234
+ <div class="row g-2">
3235
+ <div class="col-12"><label>Название варианта</label><input type="text" name="variant_name[]" class="form-control" value="{{ v.option_value }}" required></div>
3236
+ <div class="col-12 col-sm-4"><label>Цена Общая</label><input type="text" name="variant_price_regular[]" class="form-control" value="{{ v.get('price_regular', v.get('price'))|string|replace('.', ',') }}" inputmode="decimal"></div>
3237
+ <div class="col-12 col-sm-4"><label>Цена Мин.</label><input type="text" name="variant_price_min[]" class="form-control" value="{{ v.get('price_min', '0.00')|string|replace('.', ',') }}" inputmode="decimal"></div>
3238
+ <div class="col-12 col-sm-4"><label>Цена Опт.</label><input type="text" name="variant_price_wholesale[]" class="form-control" value="{{ v.get('price_wholesale', '0.00')|string|replace('.', ',') }}" inputmode="decimal"></div>
3239
+ <div class="col-12 col-sm-6"><label>Себестоимость</label><input type="text" name="variant_cost_price[]" class="form-control" value="{{ v.cost_price|string|replace('.', ',') }}" inputmode="decimal"></div>
3240
+ <div class="col-12 col-sm-6"><label>Остаток</label><input type="number" name="variant_stock[]" class="form-control" value="{{ v.stock }}"></div>
3241
+ </div>
3242
+ </div>
3243
+ <div class="col-12 text-end">
3244
+ <button type="button" class="btn btn-sm btn-danger remove-variant-btn"><i class="fas fa-times"></i> Удалить вариант</button>
3245
+ </div>
3246
+ </div>
3247
+ </div>
 
 
 
3248
  </div>
3249
+ {% endfor %}
3250
  </div>
3251
  <button type="button" class="btn btn-sm btn-outline-success mt-2 add-variant-btn-edit" data-target-container="variants-container-edit-{{ p.id }}">Добавить вариант</button>
3252
  </div>
 
3354
  let currentScanner = null;
3355
  let currentScannerContainer = null;
3356
  const placeholderImg = "{{ url_for('static', filename='placeholder.png') }}";
3357
+ const inventoryData = {{ inventory|tojson|safe }};
3358
  const isAdmin = {{ 'true' if session.admin_logged_in else 'false' }};
3359
 
3360
  function startScannerFor(containerId, inputElement, callback) {
 
3556
  </div>
3557
  </div>
3558
  `;
 
 
3559
  return div;
3560
  };
3561
 
 
3565
  }
3566
  });
3567
 
 
 
 
 
 
 
 
 
 
 
 
3568
  document.body.addEventListener('click', e => {
3569
+ if (e.target.closest('#add-variant-btn-add')) {
3570
+ document.getElementById('variants-container-add').appendChild(createVariantRow());
3571
+ return;
3572
+ }
3573
+
3574
+ const editAddBtn = e.target.closest('.add-variant-btn-edit');
3575
+ if (editAddBtn) {
3576
+ const containerId = editAddBtn.dataset.targetContainer;
3577
+ document.getElementById(containerId).appendChild(createVariantRow());
3578
+ return;
3579
+ }
3580
+
3581
  if (e.target.closest('.remove-variant-btn')) {
3582
  e.target.closest('.variant-row').remove();
3583
+ return;
3584
  }
3585
  });
3586
 
 
4064
  ITEM_MOVEMENT_SCRIPTS = """
4065
  <script>
4066
  document.addEventListener('DOMContentLoaded', () => {
4067
+ const inventoryData = {{ inventory|tojson|safe }};
4068
  const searchInput = document.getElementById('movement-search');
4069
  const searchResults = document.getElementById('movement-search-results');
4070
  const productIdInput = document.getElementById('movement-product-id');