|
1 | 1 | ActiveAdmin.register Quote do |
2 | | - permit_params :customer_id, :user_id, |
3 | | - quote_items_attributes: [:id, |
4 | | - :_destroy, |
5 | | - :quote_id, |
6 | | - :item_id, |
7 | | - :open_parameters, |
8 | | - :price, |
9 | | - :discount, |
10 | | - :final_price] |
| 2 | + permit_params :customer_id, :user_id, category_ids: [], |
| 3 | + quote_items_attributes: [:id, |
| 4 | + :_destroy, |
| 5 | + :quote_id, |
| 6 | + :item_id, |
| 7 | + :open_parameters, |
| 8 | + :price, |
| 9 | + :discount, |
| 10 | + :final_price] |
11 | 11 |
|
12 | 12 | filter :customer_name, as: :string, label: 'Customer Name' |
13 | 13 | filter :user, as: :select, collection: proc { |
|
34 | 34 | f.inputs do |
35 | 35 | f.input :customer, as: :select, collection: Customer.pluck(:company_name, :id) |
36 | 36 | f.input :user, as: :select, collection: User.order(:email).map { |u| ["#{u.email} (#{u.name})", u.id] } |
37 | | - f.input :total_price, input_html: { disabled: true } |
| 37 | + f.input :categories, as: :check_boxes, collection: Category.pluck(:name, :id) |
38 | 38 | end |
39 | | - f.inputs "Quote Items" do |
40 | | - f.has_many :quote_items, allow_destroy: true, new_record: true do |qi| |
41 | | - qi.input :item, as: :select, collection: Item.pluck(:name, :id) |
42 | | - qi.input :open_parameters |
43 | | - qi.input :price |
44 | | - qi.input :discount |
45 | | - end |
| 39 | + div do |
| 40 | + button_tag 'Load Items from Category', type: 'button', id: 'load-items-button', class: 'button' |
46 | 41 | end |
47 | 42 | f.actions |
| 43 | + # JS to load items dynamically |
| 44 | + script do |
| 45 | + raw <<-JS |
| 46 | + document.addEventListener("DOMContentLoaded", function () { |
| 47 | + const button = document.getElementById("load-items-button"); |
| 48 | + button?.addEventListener("click", function () { |
| 49 | + const selectedCategories = Array.from(document.querySelectorAll("input[name='quote[category_ids][]']:checked")).map(cb => cb.value); |
| 50 | +
|
| 51 | + if (selectedCategories.length === 0) { |
| 52 | + alert("Please select at least one category."); |
| 53 | + return; |
| 54 | + } |
| 55 | +
|
| 56 | + fetch("/admin/quotes/load_items_from_categories", { |
| 57 | + method: "POST", |
| 58 | + headers: { |
| 59 | + "Content-Type": "application/json", |
| 60 | + "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').getAttribute("content") |
| 61 | + }, |
| 62 | + body: JSON.stringify({ category_ids: selectedCategories }) |
| 63 | + }) |
| 64 | + .then(response => response.json()) |
| 65 | + .then(items => { |
| 66 | + const container = document.querySelector(".has_many_container.quote_items"); |
| 67 | +
|
| 68 | + items.forEach(item => { |
| 69 | + const addButton = container.querySelector(".has_many_add"); |
| 70 | + addButton.click(); |
| 71 | +
|
| 72 | + setTimeout(() => { |
| 73 | + const lastItemGroup = container.querySelectorAll(".has_many_fields").item(-1); |
| 74 | + const itemSelect = lastItemGroup.querySelector("select[id$='_item_id']"); |
| 75 | + const openParams = lastItemGroup.querySelector("input[id$='_open_parameters']"); |
| 76 | + const discount = lastItemGroup.querySelector("input[id$='_discount']"); |
| 77 | +
|
| 78 | + if (itemSelect) { |
| 79 | + itemSelect.value = item.item_id; |
| 80 | + } |
| 81 | + if (openParams) { |
| 82 | + openParams.value = item.open_parameters; |
| 83 | + } |
| 84 | + if (discount) { |
| 85 | + discount.value = item.discount; |
| 86 | + } |
| 87 | + }, 100); |
| 88 | + }); |
| 89 | + }); |
| 90 | + }); |
| 91 | + }); |
| 92 | + JS |
| 93 | + end |
48 | 94 | end |
49 | 95 |
|
50 | 96 | show do |
|
68 | 114 | end |
69 | 115 | end |
70 | 116 | end |
| 117 | + |
| 118 | + collection_action :load_items_from_categories, method: :post do |
| 119 | + category_ids = params[:category_ids] || [] |
| 120 | + items = Item.where(category_id: category_ids) |
| 121 | + |
| 122 | + render json: items.map { |item| |
| 123 | + { |
| 124 | + item_id: item.id, |
| 125 | + item_name: item.name, |
| 126 | + open_parameters: '', |
| 127 | + discount: 0 |
| 128 | + } |
| 129 | + } |
| 130 | + end |
71 | 131 | end |
0 commit comments