Class: CloverSandboxSimulator::Generators::EntityGenerator
- Inherits:
-
Object
- Object
- CloverSandboxSimulator::Generators::EntityGenerator
- Defined in:
- lib/clover_sandbox_simulator/generators/entity_generator.rb
Overview
Creates restaurant entities in Clover (categories, items, discounts, etc.)
Constant Summary collapse
- DEFAULT_EMPLOYEE_COUNT =
Configuration constants
5- DEFAULT_CUSTOMER_COUNT =
20- LOG_SEPARATOR =
"=" * 60
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#services ⇒ Object
readonly
Returns the value of attribute services.
Instance Method Summary collapse
-
#assign_item_tax_rates(items, tax_rates) ⇒ Object
Assign tax rates to items based on category mapping Assign tax rates to items based on category mapping (idempotent).
-
#build_item_tax_association_lookup(items, tax_rates) ⇒ Hash
Build lookup of existing item-tax associations.
-
#delete_all ⇒ Object
Delete all entities (for clean slate).
-
#ensure_modifiers_for_group(group, expected_modifiers) ⇒ Object
Ensure all modifiers exist within a group (idempotent).
-
#initialize(services: nil, business_type: :restaurant) ⇒ EntityGenerator
constructor
A new instance of EntityGenerator.
-
#setup_all ⇒ Object
Set up all entities (categories, items, discounts, etc.).
-
#setup_categories ⇒ Object
Create categories from data file.
-
#setup_customers ⇒ Object
Ensure customers exist.
-
#setup_discounts ⇒ Object
Create discounts from data file.
-
#setup_employees ⇒ Object
Ensure employees exist.
-
#setup_items ⇒ Object
Create items from data file.
-
#setup_modifier_groups ⇒ Object
Create modifier groups from data file Ensures both groups AND their child modifiers exist (idempotent).
-
#setup_order_types ⇒ Object
Set up order types (Dine In, Takeout, Delivery, etc.).
-
#setup_tax_rates ⇒ Object
Set up tax rates from data file.
Constructor Details
#initialize(services: nil, business_type: :restaurant) ⇒ EntityGenerator
Returns a new instance of EntityGenerator.
14 15 16 17 18 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 14 def initialize(services: nil, business_type: :restaurant) @services = services || Services::Clover::ServicesManager.new @data = DataLoader.new(business_type: business_type) @logger = CloverSandboxSimulator.logger end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
12 13 14 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 12 def data @data end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
12 13 14 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 12 def logger @logger end |
#services ⇒ Object (readonly)
Returns the value of attribute services.
12 13 14 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 12 def services @services end |
Instance Method Details
#assign_item_tax_rates(items, tax_rates) ⇒ Object
Assign tax rates to items based on category mapping Assign tax rates to items based on category mapping (idempotent)
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 266 def assign_item_tax_rates(items, tax_rates) logger.info "Assigning tax rates to items by category..." category_mapping = data.category_tax_mapping return if category_mapping.empty? || tax_rates.empty? # Build lookup for tax rates by name tax_rate_lookup = tax_rates.each_with_object({}) do |rate, hash| hash[rate["name"]&.downcase] = rate["id"] end # Build lookup of existing item-tax associations existing_associations = build_item_tax_association_lookup(items, tax_rates) assigned_count = 0 skipped_count = 0 items.each do |item| category = item.dig("categories", "elements", 0, "name") || item["category"] next unless category applicable_taxes = category_mapping[category] || category_mapping["default"] || [] applicable_taxes.each do |tax_name| tax_rate_id = tax_rate_lookup[tax_name.downcase] next unless tax_rate_id # Check if association already exists item_associations = existing_associations[item["id"]] || [] if item_associations.include?(tax_rate_id) skipped_count += 1 next end begin services.tax.associate_item_with_tax_rate(item["id"], tax_rate_id) assigned_count += 1 rescue StandardError => e logger.debug "Could not assign tax to item #{item["id"]}: #{e.}" end end end logger.info "Assigned #{assigned_count} new tax rate associations (#{skipped_count} already existed)" end |
#build_item_tax_association_lookup(items, tax_rates) ⇒ Hash
Build lookup of existing item-tax associations
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 313 def build_item_tax_association_lookup(items, tax_rates) associations = {} # Try to fetch existing associations from each tax rate tax_rates.each do |rate| begin items_for_rate = services.tax.get_items_for_tax_rate(rate["id"]) items_for_rate.each do |item| associations[item["id"]] ||= [] associations[item["id"]] << rate["id"] end rescue StandardError => e logger.debug "Could not fetch items for tax rate #{rate["id"]}: #{e.}" end end associations end |
#delete_all ⇒ Object
Delete all entities (for clean slate)
333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 333 def delete_all logger.warn "=" * 60 logger.warn "DELETING ALL ENTITIES..." logger.warn "=" * 60 services.inventory.delete_all services.discount.get_discounts.each do |d| services.discount.delete_discount(d["id"]) end logger.info "All entities deleted" end |
#ensure_modifiers_for_group(group, expected_modifiers) ⇒ Object
Ensure all modifiers exist within a group (idempotent)
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 192 def ensure_modifiers_for_group(group, expected_modifiers) return if expected_modifiers.empty? # Get existing modifiers for this group existing_modifiers = group.dig("modifiers", "elements") || [] existing_names = existing_modifiers.map { |m| m["name"]&.downcase } missing_count = 0 expected_modifiers.each do |mod_data| next if existing_names.include?(mod_data["name"]&.downcase) logger.debug " Creating missing modifier: #{mod_data["name"]}" services.inventory.create_modifier( modifier_group_id: group["id"], name: mod_data["name"], price: mod_data["price"] || 0 ) missing_count += 1 end logger.info " Created #{missing_count} missing modifiers for '#{group["name"]}'" if missing_count > 0 end |
#setup_all ⇒ Object
Set up all entities (categories, items, discounts, etc.)
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 21 def setup_all logger.info LOG_SEPARATOR logger.info "Setting up restaurant entities in Clover..." logger.info LOG_SEPARATOR results = { categories: setup_categories, items: setup_items, modifier_groups: setup_modifier_groups, discounts: setup_discounts, employees: setup_employees, customers: setup_customers, order_types: setup_order_types, tax_rates: setup_tax_rates } # Assign tax rates to items based on category assign_item_tax_rates(results[:items], results[:tax_rates]) if results[:items].any? && results[:tax_rates].any? logger.info LOG_SEPARATOR logger.info "Entity setup complete!" logger.info " Categories: #{results[:categories].size}" logger.info " Items: #{results[:items].size}" logger.info " Modifier Groups: #{results[:modifier_groups].size}" logger.info " Discounts: #{results[:discounts].size}" logger.info " Employees: #{results[:employees].size}" logger.info " Customers: #{results[:customers].size}" logger.info " Order Types: #{results[:order_types].size}" logger.info " Tax Rates: #{results[:tax_rates].size}" logger.info LOG_SEPARATOR results end |
#setup_categories ⇒ Object
Create categories from data file
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 56 def setup_categories logger.info "Setting up categories..." existing = services.inventory.get_categories existing_names = existing.map { |c| c["name"]&.downcase } created = [] data.categories.each do |cat_data| if existing_names.include?(cat_data["name"]&.downcase) logger.debug "Category '#{cat_data["name"]}' already exists, skipping" created << existing.find { |c| c["name"] == cat_data["name"] } else cat = services.inventory.create_category( name: cat_data["name"], sort_order: cat_data["sort_order"] ) created << cat if cat end end logger.info "Categories ready: #{created.size}" created end |
#setup_customers ⇒ Object
Ensure customers exist
224 225 226 227 228 229 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 224 def setup_customers logger.info "Setting up customers..." customers = services.customer.ensure_customers(count: DEFAULT_CUSTOMER_COUNT) logger.info "Customers ready: #{customers.size}" customers end |
#setup_discounts ⇒ Object
Create discounts from data file
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 115 def setup_discounts logger.info "Setting up discounts..." existing = services.discount.get_discounts existing_names = existing.map { |d| d["name"]&.downcase } created = [] data.discounts.each do |disc_data| if existing_names.include?(disc_data["name"]&.downcase) logger.debug "Discount '#{disc_data["name"]}' already exists, skipping" created << existing.find { |d| d["name"] == disc_data["name"] } else disc = if disc_data["percentage"] services.discount.create_percentage_discount( name: disc_data["name"], percentage: disc_data["percentage"] ) else services.discount.create_fixed_discount( name: disc_data["name"], amount: disc_data["amount"] ) end created << disc if disc end end logger.info "Discounts ready: #{created.size}" created end |
#setup_employees ⇒ Object
Ensure employees exist
216 217 218 219 220 221 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 216 def setup_employees logger.info "Setting up employees..." employees = services.employee.ensure_employees(count: DEFAULT_EMPLOYEE_COUNT) logger.info "Employees ready: #{employees.size}" employees end |
#setup_items ⇒ Object
Create items from data file
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 81 def setup_items logger.info "Setting up menu items..." # Build category lookup categories = services.inventory.get_categories category_lookup = categories.each_with_object({}) do |cat, hash| hash[cat["name"]] = cat["id"] end existing = services.inventory.get_items existing_names = existing.map { |i| i["name"]&.downcase } created = [] data.items.each do |item_data| if existing_names.include?(item_data["name"]&.downcase) logger.debug "Item '#{item_data["name"]}' already exists, skipping" created << existing.find { |i| i["name"] == item_data["name"] } else category_id = category_lookup[item_data["category"]] item = services.inventory.create_item( name: item_data["name"], price: item_data["price"], category_id: category_id ) created << item if item end end logger.info "Items ready: #{created.size}" created end |
#setup_modifier_groups ⇒ Object
Create modifier groups from data file Ensures both groups AND their child modifiers exist (idempotent)
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 148 def setup_modifier_groups logger.info "Setting up modifier groups..." existing = services.inventory.get_modifier_groups existing_by_name = existing.each_with_object({}) { |mg, h| h[mg["name"]&.downcase] = mg } created = [] data.modifiers.each do |group_data| group_name_lower = group_data["name"]&.downcase if existing_by_name.key?(group_name_lower) # Group exists - but ensure modifiers are also present group = existing_by_name[group_name_lower] logger.debug "Modifier group '#{group_data["name"]}' already exists, checking modifiers..." ensure_modifiers_for_group(group, group_data["modifiers"] || []) created << group else # Create new group and its modifiers group = services.inventory.create_modifier_group( name: group_data["name"], min_required: group_data["min_required"] || 0, max_allowed: group_data["max_allowed"] ) if group && group["id"] # Create modifiers within the group (group_data["modifiers"] || []).each do |mod_data| services.inventory.create_modifier( modifier_group_id: group["id"], name: mod_data["name"], price: mod_data["price"] || 0 ) end end created << group if group end end logger.info "Modifier groups ready: #{created.size}" created end |
#setup_order_types ⇒ Object
Set up order types (Dine In, Takeout, Delivery, etc.)
232 233 234 235 236 237 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 232 def setup_order_types logger.info "Setting up order types..." order_types = services.order_type.setup_default_order_types logger.info "Order types ready: #{order_types.size}" order_types end |
#setup_tax_rates ⇒ Object
Set up tax rates from data file
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/clover_sandbox_simulator/generators/entity_generator.rb', line 240 def setup_tax_rates logger.info "Setting up tax rates..." existing = services.tax.get_tax_rates existing_names = existing.map { |r| r["name"]&.downcase } created = [] data.tax_rates.each do |rate_data| if existing_names.include?(rate_data["name"].downcase) logger.debug "Tax rate '#{rate_data["name"]}' already exists, skipping" created << existing.find { |r| r["name"]&.downcase == rate_data["name"].downcase } else rate = services.tax.create_tax_rate( name: rate_data["name"], rate: rate_data["rate"], is_default: rate_data["is_default"] || false ) created << rate if rate end end logger.info "Tax rates ready: #{created.size}" created end |