clover_sandbox_simulator 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15537c1595b19f0f0c351e4650b65ac23316538b7fbc5e3b55bb71c798cba25a
4
- data.tar.gz: 6205e71eb9af6a625e5b95024156e2579fe8a687c274178f7a3aa255dc4a13ae
3
+ metadata.gz: 7cbba3e7549afdbb163ab890407d2627bc9fda35641bf4b56395d11ff36a89c6
4
+ data.tar.gz: a97d72dc86001e853542ca055142f788b00c79f15c60f5bb13cd662b56c5a4e1
5
5
  SHA512:
6
- metadata.gz: 2c3407b953637dc1ddf428f5795befc91969b8c0fb99c67b86c15e93cc6c02a7a9567367991135724e4920426cbd1cd0dcf4c65227aef0fa9600e9510246c838
7
- data.tar.gz: 6602102b44527baa4aca0181174d5732407c207bb6139588b010f0c06775b61c80421b31bf0ea6b4b089e1cfa1f74379a151effcc76d384c2fd6d51ec5678729
6
+ metadata.gz: f2c979158af6fea16d2d603583a2079ab63eaf6506922baa5c4885d2467c7d828edf140ddd9297657f9735d8ac46bb1ca15ebb1087c4d45d77d4572ef0ebc354
7
+ data.tar.gz: c3247b3bbd45f6b2cff03453c7a63b7594a80450f36e4d94d2e832579812231a0c3a61db89fc7841312fbbae258e488cc0fa4a54be4e96a4f1cdab28ecbdc59e
data/README.md CHANGED
@@ -5,14 +5,19 @@ A Ruby gem for simulating Point of Sale operations in Clover sandbox environment
5
5
  ## Features
6
6
 
7
7
  - **Realistic Restaurant Data**: Complete menu with 39 items across 7 categories (appetizers, entrees, sides, desserts, drinks, alcoholic beverages, specials)
8
- - **Safe Sandbox Payments**: Uses Cash, Check, Gift Card, and other safe tenders (avoids broken Credit/Debit cards in Clover sandbox)
8
+ - **Modifier Groups**: Temperature, add-ons, sides, dressings, drink sizes applied to menu items
9
+ - **Multiple Payment Methods**: Supports Credit/Debit cards via Ecommerce API, plus Cash, Check, Gift Card, and other tenders
9
10
  - **Split Payments**: Supports 1-4 tender splits per order, more common for larger parties
10
11
  - **Meal Period Simulation**: Orders distributed across breakfast, lunch, happy hour, dinner, and late night with realistic weights
11
- - **Dining Options**: Dine-in, To-Go, and Delivery with period-appropriate distributions
12
+ - **Order Types**: Dine-in, Takeout, and Delivery with configurable settings
13
+ - **Service Charges**: Auto-gratuity for large parties (18% for 6+ guests)
12
14
  - **Dynamic Order Volume**: Different order counts for weekdays, Friday, Saturday, Sunday (40-120 orders/day)
13
15
  - **Tips & Taxes**: Variable tip rates by dining option (15-25% dine-in, 0-15% takeout, 10-20% delivery)
16
+ - **Per-Item Tax Rates**: Different tax rates for food vs alcohol items
14
17
  - **Discounts**: 7 discount types including Happy Hour, Senior, Military, Employee, Birthday, and fixed amounts
15
18
  - **Employees & Customers**: Auto-generated with realistic names and contact info
19
+ - **Shift Tracking**: Clock in/out for employees with duration tracking
20
+ - **Cash Drawer Management**: Open/close drawer events with cash tracking
16
21
  - **Party Size Variation**: 1-6 guests affecting item counts and split payment probability
17
22
  - **Order Notes**: Random special instructions (allergies, modifications, VIP customers)
18
23
 
@@ -38,18 +43,39 @@ gem install clover_sandbox_simulator
38
43
 
39
44
  ## Configuration
40
45
 
41
- Copy the sample environment file and configure your Clover credentials:
42
-
43
- ```bash
44
- cp .env.sample .env
46
+ ### Multi-Merchant Setup (Recommended)
47
+
48
+ Create a `.env.json` file with multiple merchant configurations:
49
+
50
+ ```json
51
+ [
52
+ {
53
+ "CLOVER_MERCHANT_ID": "YOUR_MERCHANT_ID",
54
+ "CLOVER_MERCHANT_NAME": "My Test Merchant",
55
+ "CLOVER_API_TOKEN": "static-api-token",
56
+ "CLOVER_ACCESS_TOKEN": "oauth-jwt-token",
57
+ "CLOVER_REFRESH_TOKEN": "clvroar-refresh-token",
58
+ "PUBLIC_TOKEN": "ecommerce-public-token",
59
+ "PRIVATE_TOKEN": "ecommerce-private-token"
60
+ }
61
+ ]
45
62
  ```
46
63
 
47
- Edit `.env` with your Clover sandbox credentials:
64
+ **Token Types:**
65
+ - `CLOVER_API_TOKEN` - Static API token (never expires, preferred)
66
+ - `CLOVER_ACCESS_TOKEN` - OAuth JWT token (expires, can be refreshed)
67
+ - `PUBLIC_TOKEN` / `PRIVATE_TOKEN` - Required for credit card payments via Ecommerce API
68
+
69
+ ### Single Merchant Setup
70
+
71
+ Alternatively, use a `.env` file:
48
72
 
49
73
  ```env
50
74
  CLOVER_MERCHANT_ID=your_merchant_id
51
75
  CLOVER_API_TOKEN=your_api_token
52
76
  CLOVER_ENVIRONMENT=https://sandbox.dev.clover.com/
77
+ PUBLIC_TOKEN=your_ecommerce_public_token
78
+ PRIVATE_TOKEN=your_ecommerce_private_token
53
79
  LOG_LEVEL=INFO
54
80
  TAX_RATE=8.25
55
81
  ```
@@ -67,6 +93,9 @@ Run a full simulation (setup + generate orders):
67
93
  ### Commands
68
94
 
69
95
  ```bash
96
+ # List available merchants from .env.json
97
+ ./bin/simulate merchants
98
+
70
99
  # Set up restaurant entities (categories, items, discounts, etc.)
71
100
  ./bin/simulate setup
72
101
 
@@ -76,14 +105,17 @@ Run a full simulation (setup + generate orders):
76
105
  # Generate a specific number of orders
77
106
  ./bin/simulate generate -n 25
78
107
 
108
+ # Generate orders with refunds (5% default, customize with -r)
109
+ ./bin/simulate generate -n 25 -r 10
110
+
79
111
  # Generate a realistic full day of restaurant operations
80
112
  ./bin/simulate day
81
113
 
82
114
  # Generate a busy day (2x normal volume)
83
- ./bin/simulate day -m 2.0
115
+ ./bin/simulate day -x 2.0
84
116
 
85
117
  # Generate a slow day (0.5x normal volume)
86
- ./bin/simulate day -m 0.5
118
+ ./bin/simulate day -x 0.5
87
119
 
88
120
  # Generate a lunch or dinner rush
89
121
  ./bin/simulate rush -p lunch -n 20
@@ -92,9 +124,42 @@ Run a full simulation (setup + generate orders):
92
124
  # Run full simulation (setup + orders)
93
125
  ./bin/simulate full
94
126
 
95
- # Check current status
127
+ # Check current status (all entities)
96
128
  ./bin/simulate status
97
129
 
130
+ # Use a specific merchant by index or ID
131
+ ./bin/simulate status -i 0
132
+ ./bin/simulate generate -m YOUR_MERCHANT_ID
133
+
134
+ # Gift card operations
135
+ ./bin/simulate gift_cards # List all gift cards
136
+ ./bin/simulate gift_card_create -a 5000 # Create $50 gift card
137
+ ./bin/simulate gift_card_balance -i CARD_ID # Check balance
138
+ ./bin/simulate gift_card_reload -i CARD_ID -a 2500 # Add $25
139
+ ./bin/simulate gift_card_redeem -i CARD_ID -a 1000 # Use $10
140
+
141
+ # Refund operations
142
+ ./bin/simulate refunds # List all refunds
143
+ ./bin/simulate refund -p PAYMENT_ID # Full refund
144
+ ./bin/simulate refund -p PAYMENT_ID -a 500 # Partial refund ($5)
145
+
146
+ # Inventory & Modifiers
147
+ ./bin/simulate modifier_groups # List modifier groups
148
+ ./bin/simulate tax_rates # List tax rates
149
+
150
+ # Order Types & Service Charges
151
+ ./bin/simulate order_types # List order types (Dine In, Takeout, etc.)
152
+ ./bin/simulate service_charges # List service charges
153
+
154
+ # Shift Management
155
+ ./bin/simulate shifts # List active shifts
156
+ ./bin/simulate shift_clock_in -e EMP_ID # Clock in an employee
157
+ ./bin/simulate shift_clock_out -e EMP_ID # Clock out an employee
158
+
159
+ # Cash Drawer Operations
160
+ ./bin/simulate cash_open_drawer -a 10000 # Open drawer with $100 starting cash
161
+ ./bin/simulate cash_close_drawer -e EMP_ID # Close drawer for employee
162
+
98
163
  # Delete all entities (requires confirmation)
99
164
  ./bin/simulate delete --confirm
100
165
 
@@ -127,11 +192,42 @@ Run a full simulation (setup + generate orders):
127
192
  | Drinks | Soft Drink | $2.99 |
128
193
  | Alcoholic | Draft Beer | $5.99 |
129
194
 
130
- ## Payment Tenders
195
+ ### Modifier Groups
196
+
197
+ | Group | Options | Example Use |
198
+ |-------|---------|-------------|
199
+ | Temperature | Rare, Medium Rare, Medium, Medium Well, Well Done | Steaks, Burgers |
200
+ | Add-Ons | Extra Cheese (+$1.50), Bacon (+$2.00), Avocado (+$1.75) | Burgers, Sandwiches |
201
+ | Side Choice | French Fries, Sweet Potato Fries, Onion Rings, Salad | Entrees |
202
+ | Dressing | Ranch, Blue Cheese, Caesar, Balsamic, Honey Mustard | Salads |
203
+ | Drink Size | Small, Medium, Large | Beverages |
131
204
 
132
- **IMPORTANT**: Credit Card and Debit Card are **broken** in Clover sandbox. This gem intentionally avoids them.
205
+ ## Payment Methods
133
206
 
134
- Safe tenders used:
207
+ ### Credit/Debit Card Payments (Ecommerce API)
208
+
209
+ Credit and debit card payments are fully supported via the **Clover Ecommerce API**. This requires configuring `PUBLIC_TOKEN` and `PRIVATE_TOKEN` in your `.env.json`.
210
+
211
+ **Test Card Numbers:**
212
+
213
+ | Card Type | Number |
214
+ |-----------|--------|
215
+ | Visa | 4242424242424242 |
216
+ | Visa Debit | 4005562231212123 |
217
+ | Mastercard | 5200828282828210 |
218
+ | Amex | 378282246310005 |
219
+ | Discover | 6011111111111117 |
220
+ | Decline (test) | 4000000000000002 |
221
+ | Insufficient Funds (test) | 4000000000009995 |
222
+
223
+ **Ecommerce API Endpoints:**
224
+ - Tokenization: `https://token-sandbox.dev.clover.com/v1/tokens`
225
+ - Charges: `https://scl-sandbox.dev.clover.com/v1/charges`
226
+ - Refunds: `https://scl-sandbox.dev.clover.com/v1/refunds`
227
+
228
+ ### Platform API Tenders
229
+
230
+ For non-card payments, the simulator uses Platform API tenders:
135
231
  - Cash (preferred for orders under $20)
136
232
  - Check
137
233
  - Gift Card
@@ -139,7 +235,84 @@ Safe tenders used:
139
235
  - Mobile Payment
140
236
  - Store Credit
141
237
 
142
- The simulator uses whatever safe tenders are available in the Clover merchant account.
238
+ The simulator uses whatever tenders are available in the Clover merchant account.
239
+
240
+ ## Tax Rates
241
+
242
+ The simulator supports per-item tax rates based on category:
243
+
244
+ | Category | Tax Rate | Notes |
245
+ |----------|----------|-------|
246
+ | Food Items | 8.25% | Standard sales tax |
247
+ | Alcoholic Beverages | 8.25% + 10% | Sales tax + alcohol tax |
248
+
249
+ Tax rates are automatically assigned to items during setup based on their category.
250
+
251
+ ## Service Charges
252
+
253
+ ### Auto-Gratuity
254
+
255
+ Large parties (6+ guests) automatically receive an 18% auto-gratuity service charge. This is:
256
+ - Added to the order subtotal before payment
257
+ - Displayed as a separate line item
258
+ - Configurable via the `ServiceChargeService`
259
+
260
+ **Note:** Service charges must be pre-configured in the Clover dashboard for sandbox environments, as the API may not support creating them dynamically.
261
+
262
+ ## Order Types
263
+
264
+ The simulator supports multiple order types that affect order flow and reporting:
265
+
266
+ | Order Type | Description |
267
+ |------------|-------------|
268
+ | Dine In | In-restaurant dining |
269
+ | Takeout | Customer pickup |
270
+ | Delivery | Delivery orders |
271
+ | Online | Online/web orders |
272
+ | Catering | Large catering orders |
273
+
274
+ Order types are automatically created during setup if they don't exist.
275
+
276
+ ## Shift Management
277
+
278
+ The simulator tracks employee shifts for realistic operations:
279
+
280
+ ```ruby
281
+ # Clock in an employee
282
+ services.shift.clock_in(employee_id: "EMP_123")
283
+
284
+ # Clock out an employee
285
+ services.shift.clock_out(employee_id: "EMP_123")
286
+
287
+ # Get active shifts
288
+ services.shift.get_active_shifts
289
+
290
+ # Calculate shift duration
291
+ services.shift.calculate_shift_duration(shift_id: "SHIFT_123")
292
+ ```
293
+
294
+ ## Cash Drawer Operations
295
+
296
+ Track cash drawer operations for end-of-day reconciliation:
297
+
298
+ ```ruby
299
+ # Open cash drawer
300
+ services.cash_event.open_drawer(employee_id: "EMP_123", amount: 10000)
301
+
302
+ # Close cash drawer
303
+ services.cash_event.close_drawer(employee_id: "EMP_123", amount: 15000)
304
+
305
+ # Add cash (e.g., from cash payment)
306
+ services.cash_event.add_cash(employee_id: "EMP_123", amount: 2500, note: "Cash sale")
307
+
308
+ # Remove cash (e.g., cash out)
309
+ services.cash_event.remove_cash(employee_id: "EMP_123", amount: 5000, note: "Bank deposit")
310
+
311
+ # Get drawer total
312
+ services.cash_event.calculate_drawer_total
313
+ ```
314
+
315
+ **Note:** Cash event creation may not be fully supported in the Clover sandbox. The simulator handles this gracefully with simulated responses.
143
316
 
144
317
  ## Tips
145
318
 
@@ -197,31 +370,41 @@ clover_sandbox_simulator/
197
370
  ├── lib/
198
371
  │ ├── clover_sandbox_simulator.rb # Gem entry point
199
372
  │ └── clover_sandbox_simulator/
200
- │ ├── configuration.rb # Environment config
373
+ │ ├── configuration.rb # Multi-merchant config from .env.json
374
+ │ ├── parallel_executor.rb # Concurrent execution support
201
375
  │ ├── services/
202
- │ │ ├── base_service.rb
376
+ │ │ ├── base_service.rb # HTTP client, error handling helpers
203
377
  │ │ └── clover/ # Clover API services
204
- │ │ ├── inventory_service.rb
205
- │ │ ├── order_service.rb
206
- │ │ ├── payment_service.rb
207
- │ │ ├── tender_service.rb
208
- │ │ ├── tax_service.rb
209
- │ │ ├── discount_service.rb
210
- │ │ ├── employee_service.rb
211
- │ │ ├── customer_service.rb
212
- │ │ └── services_manager.rb
378
+ │ │ ├── inventory_service.rb # Categories, items, modifier groups
379
+ │ │ ├── order_service.rb # Orders, line items, modifiers
380
+ │ │ ├── payment_service.rb # Payments, splits
381
+ │ │ ├── tender_service.rb # Payment tenders
382
+ │ │ ├── tax_service.rb # Tax rates, per-item taxes
383
+ │ │ ├── discount_service.rb # Discounts, promos, combos
384
+ │ │ ├── employee_service.rb # Employee management
385
+ │ │ ├── customer_service.rb # Customer management
386
+ │ │ ├── ecommerce_service.rb # Card payments via Ecommerce API
387
+ │ │ ├── refund_service.rb # Full/partial refunds
388
+ │ │ ├── gift_card_service.rb # Gift card management
389
+ │ │ ├── service_charge_service.rb # Service charges, auto-gratuity
390
+ │ │ ├── shift_service.rb # Employee shifts, clock in/out
391
+ │ │ ├── order_type_service.rb # Order types (Dine In, Takeout, etc.)
392
+ │ │ ├── cash_event_service.rb # Cash drawer operations
393
+ │ │ ├── oauth_service.rb # Token refresh
394
+ │ │ └── services_manager.rb # Thread-safe service access
213
395
  │ ├── generators/
214
- │ │ ├── data_loader.rb
215
- │ │ ├── entity_generator.rb
216
- │ │ └── order_generator.rb
396
+ │ │ ├── data_loader.rb # Load JSON data files
397
+ │ │ ├── entity_generator.rb # Setup entities (idempotent)
398
+ │ │ └── order_generator.rb # Generate realistic orders
217
399
  │ └── data/
218
400
  │ └── restaurant/ # JSON data files
219
401
  │ ├── categories.json
220
402
  │ ├── items.json
221
403
  │ ├── discounts.json
222
404
  │ ├── tenders.json
223
- └── modifiers.json
224
- └── spec/ # RSpec tests
405
+ ├── modifiers.json
406
+ └── tax_rates.json
407
+ └── spec/ # RSpec tests with VCR integration
225
408
  ```
226
409
 
227
410
  ## Development
@@ -236,6 +419,9 @@ bundle exec rspec --format documentation
236
419
  # Run specific test file
237
420
  bundle exec rspec spec/services/clover/tender_service_spec.rb
238
421
 
422
+ # Run integration tests (requires .env.json with valid credentials)
423
+ bundle exec rspec spec/integration/
424
+
239
425
  # Run linter
240
426
  bundle exec rubocop
241
427
 
@@ -245,26 +431,33 @@ bundle exec irb -r ./lib/clover_sandbox_simulator
245
431
 
246
432
  ## Testing
247
433
 
248
- The gem includes comprehensive RSpec tests with WebMock for HTTP stubbing.
434
+ The gem includes comprehensive RSpec tests with WebMock for HTTP stubbing and VCR for integration tests.
249
435
 
250
436
  ### Test Coverage
251
437
 
252
- - **268 examples, 0 failures**
438
+ - **475 examples, 0 failures, 3 pending**
253
439
  - Configuration validation
254
440
  - Data loading from JSON files
255
441
  - All Clover API services:
256
- - InventoryService (categories, items)
257
- - OrderService (create, line items, dining options)
258
- - PaymentService (single and split payments)
259
- - TenderService (safe tenders, split selection)
260
- - TaxService (rates, calculation)
261
- - DiscountService (percentage and fixed)
262
- - EmployeeService (CRUD, random selection)
442
+ - InventoryService (categories, items, modifier groups)
443
+ - OrderService (create, line items, dining options, modifiers)
444
+ - PaymentService (single, split, and card payments)
445
+ - TenderService (tender selection)
446
+ - TaxService (rates, per-item calculation, item associations)
447
+ - DiscountService (percentage, fixed, time-based, loyalty)
448
+ - EmployeeService (CRUD, deterministic setup)
263
449
  - CustomerService (CRUD, anonymous orders)
264
- - ServicesManager (memoization, lazy loading)
450
+ - RefundService (full/partial refunds, multiple strategies)
451
+ - GiftCardService (create, reload, redeem)
452
+ - ServiceChargeService (auto-gratuity, apply to orders)
453
+ - ShiftService (clock in/out, active shifts)
454
+ - OrderTypeService (CRUD, default setup)
455
+ - CashEventService (drawer operations, simulated responses)
456
+ - ServicesManager (thread-safe memoization, lazy loading)
265
457
  - Entity generator idempotency
266
- - Order generator (meal periods, dining options, tips)
458
+ - Order generator (meal periods, dining options, tips, refunds, modifiers, service charges)
267
459
  - Edge cases (nil handling, empty arrays, API errors)
460
+ - VCR integration tests for real API validation
268
461
 
269
462
  ### Test Files
270
463
 
@@ -275,16 +468,28 @@ spec/
275
468
  │ ├── data_loader_spec.rb
276
469
  │ ├── entity_generator_spec.rb
277
470
  │ └── order_generator_spec.rb
278
- └── services/clover/
279
- ├── customer_service_spec.rb
280
- ├── discount_service_spec.rb
281
- ├── employee_service_spec.rb
282
- ├── inventory_service_spec.rb
283
- ├── order_service_spec.rb
284
- ├── payment_service_spec.rb
285
- ├── services_manager_spec.rb
286
- ├── tax_service_spec.rb
287
- └── tender_service_spec.rb
471
+ ├── services/clover/
472
+ ├── customer_service_spec.rb
473
+ ├── discount_service_spec.rb
474
+ ├── employee_service_spec.rb
475
+ ├── gift_card_service_spec.rb
476
+ ├── inventory_service_spec.rb
477
+ ├── order_service_spec.rb
478
+ ├── payment_service_spec.rb
479
+ ├── refund_service_spec.rb
480
+ │ ├── service_charge_service_spec.rb
481
+ │ ├── shift_service_spec.rb
482
+ │ ├── order_type_service_spec.rb
483
+ │ ├── cash_event_service_spec.rb
484
+ │ ├── tax_service_spec.rb
485
+ │ ├── services_manager_spec.rb
486
+ │ └── tender_service_spec.rb
487
+ └── integration/
488
+ ├── modifier_groups_spec.rb
489
+ ├── service_charges_spec.rb
490
+ ├── order_types_spec.rb
491
+ ├── cash_events_spec.rb
492
+ └── tax_rates_spec.rb
288
493
  ```
289
494
 
290
495
  ### Idempotency Verification
@@ -299,11 +504,28 @@ generator.setup_all # Second run: skips existing, returns same results
299
504
  ```
300
505
 
301
506
  The tests verify:
302
- - Categories are not duplicated
303
- - Items are not duplicated
304
- - Discounts are not duplicated
507
+ - Categories are not duplicated (case-insensitive matching)
508
+ - Items are not duplicated (case-insensitive matching)
509
+ - Discounts are not duplicated (case-insensitive matching)
510
+ - Modifier groups AND their child modifiers are not duplicated
511
+ - Tax rates are not duplicated
512
+ - Order types are not duplicated
305
513
  - Employees/customers only created if count threshold not met
306
514
 
515
+ ## Sandbox Limitations
516
+
517
+ Some Clover sandbox operations may return errors or behave differently than production:
518
+
519
+ | Feature | Sandbox Support | Notes |
520
+ |---------|-----------------|-------|
521
+ | Service Charge Creation | ❌ Limited | Must pre-configure in dashboard |
522
+ | Cash Event Creation | ❌ Limited | Returns 405, simulated locally |
523
+ | Item Tax Rate Fetch | ❌ Limited | Returns 405, simulated locally |
524
+ | Credit Card Payments | ✅ Full | Via Ecommerce API |
525
+ | Order Creation | ✅ Full | Today's date only |
526
+
527
+ The simulator handles these limitations gracefully with fallback behavior.
528
+
307
529
  ## Clover API Notes
308
530
 
309
531
  - **Sandbox URL**: `https://sandbox.dev.clover.com/`