spree_packeta 0.1.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 +7 -0
- data/.github/workflows/release.yml +196 -0
- data/.github/workflows/test.yml +61 -0
- data/.gitignore +63 -0
- data/CHANGELOG.md +43 -0
- data/COMMANDS.md +322 -0
- data/Gemfile +13 -0
- data/LICENSE +21 -0
- data/README.md +307 -0
- data/app/decorators/spree/order_decorator.rb +44 -0
- data/app/decorators/spree/shipment_decorator.rb +65 -0
- data/db/migrate/20241206000001_add_packeta_tracking_to_shipments.rb +14 -0
- data/docs/RELEASING.md +421 -0
- data/lib/generators/spree_packeta/install_generator.rb +68 -0
- data/lib/generators/spree_packeta/templates/initializer.rb +39 -0
- data/lib/spree_packeta/configuration.rb +55 -0
- data/lib/spree_packeta/engine.rb +48 -0
- data/lib/spree_packeta/models/shipping_calculator.rb +54 -0
- data/lib/spree_packeta/models/shipping_method.rb +59 -0
- data/lib/spree_packeta/services/packet_creator.rb +98 -0
- data/lib/spree_packeta/services/tracker.rb +96 -0
- data/lib/spree_packeta/soap/client.rb +117 -0
- data/lib/spree_packeta/soap/operations.rb +140 -0
- data/lib/spree_packeta/soap/packeta.wsdl +1819 -0
- data/lib/spree_packeta/version.rb +5 -0
- data/lib/spree_packeta.rb +18 -0
- data/lib/tasks/spree_packeta.rake +293 -0
- data/spree_packeta.gemspec +41 -0
- metadata +228 -0
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Spree Packeta
|
|
2
|
+
|
|
3
|
+
Packeta (Zasilkovna) shipping integration for Spree Commerce. This gem provides SOAP API integration for packet creation, tracking, and label generation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Phase 1 (Current)**:
|
|
8
|
+
- SOAP client wrapper for Packeta API
|
|
9
|
+
- Packet creation and tracking
|
|
10
|
+
- Shipping method and calculator integration
|
|
11
|
+
- Database tracking fields for shipments
|
|
12
|
+
|
|
13
|
+
- **Planned Features**:
|
|
14
|
+
- Dynamic rate calculation from Packeta API
|
|
15
|
+
- Label generation (PDF, PNG, ZPL)
|
|
16
|
+
- COD (Cash on Delivery) support
|
|
17
|
+
- Customs declarations
|
|
18
|
+
- Admin interface for packet management
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Add this line to your application's Gemfile:
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
gem 'spree_packeta', path: '/Users/oezr/Projects/spree_packeta'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
And then execute:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bundle install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run the installation generator:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
bundle exec rails g spree_packeta:install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This will:
|
|
41
|
+
- Copy the migration files
|
|
42
|
+
- Create an initializer with configuration
|
|
43
|
+
- Optionally run migrations
|
|
44
|
+
- Optionally install the Packeta shipping method
|
|
45
|
+
|
|
46
|
+
### Manual Installation
|
|
47
|
+
|
|
48
|
+
If you prefer to install components separately:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Copy and run migrations
|
|
52
|
+
bundle exec rails spree_packeta:install:migrations
|
|
53
|
+
bundle exec rails db:migrate
|
|
54
|
+
|
|
55
|
+
# Install Packeta shipping method
|
|
56
|
+
bundle exec rake spree_packeta:install
|
|
57
|
+
|
|
58
|
+
# Check status
|
|
59
|
+
bundle exec rake spree_packeta:status
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
Configure the gem in `config/initializers/spree_packeta.rb`:
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
SpreePacketa.configure do |config|
|
|
68
|
+
# API credentials
|
|
69
|
+
config.api_password = ENV['PACKETA_API_PASSWORD']
|
|
70
|
+
|
|
71
|
+
# SOAP endpoint (production vs sandbox)
|
|
72
|
+
config.soap_endpoint = ENV.fetch('PACKETA_SOAP_ENDPOINT',
|
|
73
|
+
'http://www.zasilkovna.cz/api/soap')
|
|
74
|
+
|
|
75
|
+
# WSDL path (can be local file or URL)
|
|
76
|
+
config.wsdl_path = ENV.fetch('PACKETA_WSDL_PATH',
|
|
77
|
+
'http://www.zasilkovna.cz/api/soap.wsdl')
|
|
78
|
+
|
|
79
|
+
# Default eshop identifier
|
|
80
|
+
config.eshop = ENV['PACKETA_ESHOP']
|
|
81
|
+
|
|
82
|
+
# Sender information for return labels
|
|
83
|
+
config.sender_name = ENV['PACKETA_SENDER_NAME']
|
|
84
|
+
config.sender_email = ENV['PACKETA_SENDER_EMAIL']
|
|
85
|
+
config.sender_phone = ENV['PACKETA_SENDER_PHONE']
|
|
86
|
+
|
|
87
|
+
# Rate caching duration (in seconds)
|
|
88
|
+
config.rate_cache_duration = 3600 # 1 hour
|
|
89
|
+
|
|
90
|
+
# Auto-create packets on shipment
|
|
91
|
+
config.auto_create_packets = true
|
|
92
|
+
|
|
93
|
+
# Sync tracking status interval
|
|
94
|
+
config.tracking_sync_interval = 1.hour
|
|
95
|
+
end
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Environment Variables
|
|
99
|
+
|
|
100
|
+
Add these to your `.env` file:
|
|
101
|
+
|
|
102
|
+
```env
|
|
103
|
+
PACKETA_API_PASSWORD=your_api_password_here
|
|
104
|
+
PACKETA_ESHOP=your_eshop_identifier
|
|
105
|
+
PACKETA_SENDER_NAME=Your Store Name
|
|
106
|
+
PACKETA_SENDER_EMAIL=shipping@yourstore.com
|
|
107
|
+
PACKETA_SENDER_PHONE=+420123456789
|
|
108
|
+
|
|
109
|
+
# Optional: Use local WSDL file
|
|
110
|
+
PACKETA_WSDL_PATH=file:///path/to/soap.wsdl
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Usage
|
|
114
|
+
|
|
115
|
+
### Quick Start with Rake Tasks
|
|
116
|
+
|
|
117
|
+
The easiest way to set up Packeta:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Install shipping method with default configuration
|
|
121
|
+
bundle exec rake spree_packeta:install
|
|
122
|
+
|
|
123
|
+
# Check installation status and configuration
|
|
124
|
+
bundle exec rake spree_packeta:status
|
|
125
|
+
|
|
126
|
+
# Remove shipping method if needed
|
|
127
|
+
bundle exec rake spree_packeta:uninstall
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The `install` task will:
|
|
131
|
+
- Create "Packeta" shipping method
|
|
132
|
+
- Set up Czech Republic and EU zones
|
|
133
|
+
- Configure the Packeta calculator with default rates (99 CZK)
|
|
134
|
+
- Assign shipping categories and zones
|
|
135
|
+
|
|
136
|
+
### Manual Setup via Admin Panel
|
|
137
|
+
|
|
138
|
+
If you prefer manual setup or need to customize:
|
|
139
|
+
|
|
140
|
+
1. Go to Settings → Shipping Methods
|
|
141
|
+
2. Click "New Shipping Method"
|
|
142
|
+
3. Fill in:
|
|
143
|
+
- **Name**: Packeta
|
|
144
|
+
- **Admin Name**: Packeta (Zásilkovna)
|
|
145
|
+
- **Code**: packeta
|
|
146
|
+
- **Display**: Both (or your preference)
|
|
147
|
+
- **Tracking URL**: `https://tracking.packeta.com/:tracking`
|
|
148
|
+
- **Shipping Categories**: Select applicable categories
|
|
149
|
+
- **Calculator**: Choose "Packeta Shipping Calculator"
|
|
150
|
+
4. Configure calculator preferences:
|
|
151
|
+
- **Amount**: Base shipping rate (e.g., 99.00)
|
|
152
|
+
- **Currency**: CZK (or your currency)
|
|
153
|
+
5. Assign to zones (Czech Republic, EU, etc.)
|
|
154
|
+
|
|
155
|
+
### Creating a Packet
|
|
156
|
+
|
|
157
|
+
The gem provides services for packet management:
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
# Create a packet from a shipment
|
|
161
|
+
service = SpreePacketa::Services::PacketCreator.new(shipment)
|
|
162
|
+
result = service.create_packet
|
|
163
|
+
|
|
164
|
+
# This will:
|
|
165
|
+
# - Extract shipment details
|
|
166
|
+
# - Call Packeta API to create packet
|
|
167
|
+
# - Store packet ID and barcode on shipment
|
|
168
|
+
# - Return packet details
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Tracking
|
|
172
|
+
|
|
173
|
+
```ruby
|
|
174
|
+
# Get current status
|
|
175
|
+
tracker = SpreePacketa::Services::Tracker.new(shipment)
|
|
176
|
+
status = tracker.current_status
|
|
177
|
+
# => { date_time: ..., status_code: ..., status_text: ..., branch_id: ... }
|
|
178
|
+
|
|
179
|
+
# Get full tracking history
|
|
180
|
+
history = tracker.tracking_history
|
|
181
|
+
# => [{ date_time: ..., status_code: ..., ... }, ...]
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Direct SOAP API Access
|
|
185
|
+
|
|
186
|
+
For advanced use cases, you can use the SOAP operations directly:
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
# Initialize operations
|
|
190
|
+
ops = SpreePacketa::Soap::Operations.new
|
|
191
|
+
|
|
192
|
+
# Create a packet
|
|
193
|
+
packet = ops.create_packet(
|
|
194
|
+
number: 'ORDER-12345',
|
|
195
|
+
name: 'John',
|
|
196
|
+
surname: 'Doe',
|
|
197
|
+
email: 'john@example.com',
|
|
198
|
+
phone: '+420123456789',
|
|
199
|
+
address_id: 1234, # Packeta pickup point ID
|
|
200
|
+
value: 1000.0,
|
|
201
|
+
weight: 2.5,
|
|
202
|
+
currency: 'CZK'
|
|
203
|
+
)
|
|
204
|
+
# => { id: 123456, barcode: '...', barcode_text: 'Z...' }
|
|
205
|
+
|
|
206
|
+
# Get packet status
|
|
207
|
+
status = ops.packet_status(packet[:id])
|
|
208
|
+
# => { status_code: 1, status_text: 'Packet created', ... }
|
|
209
|
+
|
|
210
|
+
# Get tracking history
|
|
211
|
+
history = ops.packet_tracking(packet[:id])
|
|
212
|
+
# => [{ date_time: ..., status_code: ..., ... }, ...]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Database Schema
|
|
216
|
+
|
|
217
|
+
The gem adds the following columns to `spree_shipments`:
|
|
218
|
+
|
|
219
|
+
| Column | Type | Description |
|
|
220
|
+
|---------------------------|----------|--------------------------------------|
|
|
221
|
+
| `packeta_packet_id` | bigint | Packeta packet ID |
|
|
222
|
+
| `packeta_barcode` | string | Packet barcode |
|
|
223
|
+
| `packeta_tracking_url` | string | Full tracking URL |
|
|
224
|
+
| `packeta_status_code` | integer | Latest status code |
|
|
225
|
+
| `packeta_branch_id` | integer | Current branch/pickup point ID |
|
|
226
|
+
| `packeta_last_sync_at` | datetime | Last tracking sync timestamp |
|
|
227
|
+
|
|
228
|
+
## Error Handling
|
|
229
|
+
|
|
230
|
+
The gem defines custom exceptions for different error scenarios:
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
begin
|
|
234
|
+
ops.create_packet(attributes)
|
|
235
|
+
rescue SpreePacketa::AuthenticationError => e
|
|
236
|
+
# Invalid API password
|
|
237
|
+
rescue SpreePacketa::ValidationError => e
|
|
238
|
+
# Invalid packet attributes
|
|
239
|
+
rescue SpreePacketa::NotFoundError => e
|
|
240
|
+
# Packet not found
|
|
241
|
+
rescue SpreePacketa::NetworkError => e
|
|
242
|
+
# Network/connectivity issues
|
|
243
|
+
rescue SpreePacketa::ApiError => e
|
|
244
|
+
# Other API errors
|
|
245
|
+
end
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Development
|
|
249
|
+
|
|
250
|
+
After checking out the repo, run:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
bundle install
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Running Tests
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
bundle exec rspec
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Console
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
bundle exec bin/console
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Roadmap
|
|
269
|
+
|
|
270
|
+
### Phase 2: Rate Calculation
|
|
271
|
+
- [ ] Dynamic rate calculation via Packeta API
|
|
272
|
+
- [ ] Zone-based pricing
|
|
273
|
+
- [ ] Service level support
|
|
274
|
+
- [ ] Rate caching
|
|
275
|
+
|
|
276
|
+
### Phase 3: Label Generation
|
|
277
|
+
- [ ] PDF label generation
|
|
278
|
+
- [ ] Multiple format support (PNG, ZPL)
|
|
279
|
+
- [ ] Batch label generation
|
|
280
|
+
- [ ] Label storage
|
|
281
|
+
|
|
282
|
+
### Phase 4: Advanced Features
|
|
283
|
+
- [ ] COD support
|
|
284
|
+
- [ ] Customs declarations
|
|
285
|
+
- [ ] Pickup point widget
|
|
286
|
+
- [ ] Return shipments
|
|
287
|
+
- [ ] Packet updates
|
|
288
|
+
|
|
289
|
+
### Phase 5: Admin Interface
|
|
290
|
+
- [ ] Packeta settings page
|
|
291
|
+
- [ ] Packet management
|
|
292
|
+
- [ ] Bulk operations
|
|
293
|
+
- [ ] Tracking dashboard
|
|
294
|
+
|
|
295
|
+
## Contributing
|
|
296
|
+
|
|
297
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/yourusername/spree_packeta.
|
|
298
|
+
|
|
299
|
+
## License
|
|
300
|
+
|
|
301
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
302
|
+
|
|
303
|
+
## Support
|
|
304
|
+
|
|
305
|
+
For issues specific to this gem, please open an issue on GitHub.
|
|
306
|
+
|
|
307
|
+
For Packeta API documentation and support, visit: https://www.zasilkovna.cz/api/
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SpreePacketa
|
|
4
|
+
module OrderDecorator
|
|
5
|
+
def self.prepended(base)
|
|
6
|
+
base.class_eval do
|
|
7
|
+
set_callback :updating_from_params, :before, :update_packeta_pickup_point
|
|
8
|
+
|
|
9
|
+
# Store Packeta pickup point data in order metadata
|
|
10
|
+
store_accessor :public_metadata, :packeta_pickup_point_id
|
|
11
|
+
store_accessor :public_metadata, :packeta_pickup_point_name
|
|
12
|
+
store_accessor :public_metadata, :packeta_pickup_point_address
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def update_packeta_pickup_point
|
|
17
|
+
return unless @updating_params[:order] && @updating_params[:order][:packeta_pickup_point].present?
|
|
18
|
+
set_packeta_pickup_point(@updating_params[:order].delete(:packeta_pickup_point))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Get the Packeta pickup point ID for this order
|
|
22
|
+
#
|
|
23
|
+
# @return [Integer, nil] The pickup point ID
|
|
24
|
+
def packeta_address_id
|
|
25
|
+
packeta_pickup_point_id&.to_i
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Set Packeta pickup point from widget data
|
|
29
|
+
#
|
|
30
|
+
# @param point_data [Hash] Pickup point data from Packeta widget
|
|
31
|
+
def set_packeta_pickup_point(point_data)
|
|
32
|
+
return unless point_data
|
|
33
|
+
|
|
34
|
+
self.packeta_pickup_point_id = point_data[:id]
|
|
35
|
+
self.packeta_pickup_point_name = point_data[:name]
|
|
36
|
+
|
|
37
|
+
address_parts = [point_data[:street], point_data[:city], point_data[:zip]].compact
|
|
38
|
+
|
|
39
|
+
self.packeta_pickup_point_address = address_parts.join(', ')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
Spree::Order.prepend self
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SpreePacketa
|
|
4
|
+
module ShipmentDecorator
|
|
5
|
+
def self.prepended(base)
|
|
6
|
+
base.class_eval do
|
|
7
|
+
# Hook into state machine - after successful transition to 'ready'
|
|
8
|
+
state_machine.after_transition to: :ready, do: :auto_create_packeta_packet
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
# Automatically create Packeta packet when shipment becomes ready
|
|
15
|
+
# This method is called after state transition to 'ready' is committed
|
|
16
|
+
# Errors are caught and logged but never block the shipment workflow
|
|
17
|
+
def auto_create_packeta_packet
|
|
18
|
+
# Early returns for conditions that prevent auto-creation
|
|
19
|
+
return unless should_auto_create_packet?
|
|
20
|
+
|
|
21
|
+
# Delegate to service for actual creation
|
|
22
|
+
packet_creator = SpreePacketa::Services::PacketCreator.new(self)
|
|
23
|
+
result = packet_creator.create_packet
|
|
24
|
+
|
|
25
|
+
Rails.logger.info("Auto-created Packeta packet #{result[:id]} for shipment #{id}")
|
|
26
|
+
rescue SpreePacketa::ValidationError => e
|
|
27
|
+
Rails.logger.warn("Automatic Packeta packet creation skipped for shipment #{id}: #{e.message}")
|
|
28
|
+
rescue SpreePacketa::NetworkError, SpreePacketa::ApiError => e
|
|
29
|
+
Rails.logger.error("Packeta API error during auto-creation for shipment #{id}: #{e.message}")
|
|
30
|
+
rescue StandardError => e
|
|
31
|
+
Rails.logger.error("Unexpected error during Packeta auto-creation for shipment #{id}: #{e.class} - #{e.message}")
|
|
32
|
+
Rails.logger.error(e.backtrace.first(10).join("\n"))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Determine if automatic packet creation should proceed
|
|
36
|
+
def should_auto_create_packet?
|
|
37
|
+
# Check global configuration
|
|
38
|
+
return false unless SpreePacketa.configuration.auto_create_packets
|
|
39
|
+
|
|
40
|
+
# Check if packet already exists
|
|
41
|
+
return false if packeta_packet_id.present?
|
|
42
|
+
|
|
43
|
+
# Check if this is a Packeta shipment
|
|
44
|
+
return false unless packeta_shipping_method?
|
|
45
|
+
|
|
46
|
+
# Check if pickup point is selected
|
|
47
|
+
return false unless order.packeta_pickup_point_id.present?
|
|
48
|
+
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Check if the shipping method is a Packeta shipping method
|
|
53
|
+
def packeta_shipping_method?
|
|
54
|
+
return false unless shipping_method
|
|
55
|
+
|
|
56
|
+
# Check if it's our Packeta shipping method class
|
|
57
|
+
return true if shipping_method.is_a?(SpreePacketa::Models::ShippingMethod)
|
|
58
|
+
|
|
59
|
+
# Fallback: check carrier name for admin-configured methods
|
|
60
|
+
shipping_method.carrier == 'Packeta'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
Spree::Shipment.prepend self
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class AddPacketaTrackingToShipments < ActiveRecord::Migration[7.0]
|
|
4
|
+
def change
|
|
5
|
+
add_column :spree_shipments, :packeta_packet_id, :bigint
|
|
6
|
+
add_column :spree_shipments, :packeta_barcode, :string
|
|
7
|
+
add_column :spree_shipments, :packeta_tracking_url, :string
|
|
8
|
+
add_column :spree_shipments, :packeta_status_code, :integer
|
|
9
|
+
add_column :spree_shipments, :packeta_branch_id, :integer
|
|
10
|
+
add_column :spree_shipments, :packeta_last_sync_at, :datetime
|
|
11
|
+
|
|
12
|
+
add_index :spree_shipments, :packeta_packet_id, unique: true, name: 'index_shipments_on_packeta_packet_id'
|
|
13
|
+
end
|
|
14
|
+
end
|