erp_integration 0.6.0 → 0.10.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 +4 -4
- data/.gitignore +1 -0
- data/README.md +61 -37
- data/lib/erp_integration/configuration.rb +18 -0
- data/lib/erp_integration/customer_shipment.rb +32 -0
- data/lib/erp_integration/customer_shipment_return.rb +22 -0
- data/lib/erp_integration/fulfil/api_resource.rb +2 -0
- data/lib/erp_integration/fulfil/persistence.rb +55 -0
- data/lib/erp_integration/fulfil/resources/customer_shipment.rb +13 -0
- data/lib/erp_integration/fulfil/resources/customer_shipment_return.rb +13 -0
- data/lib/erp_integration/fulfil/resources/sales_order_line.rb +39 -0
- data/lib/erp_integration/resource.rb +9 -0
- data/lib/erp_integration/resources/errors.rb +32 -0
- data/lib/erp_integration/resources/persistence.rb +40 -0
- data/lib/erp_integration/resources/validations.rb +35 -0
- data/lib/erp_integration/sales_order_line.rb +8 -0
- data/lib/erp_integration/version.rb +1 -1
- data/lib/erp_integration.rb +8 -0
- metadata +15 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2575164b921d6b45ac6cfb10141c6199faaf5b360095b5124a14b38f1e81d61
|
4
|
+
data.tar.gz: 42c7dc28adefd40ff5cf91cb3f8631547c587cb37310dfa487ab9f5b5bebe707
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebfc1904ac9116b1622be174c57cb166cf1cf15db401a561395bb00e499962f4dd59837e0657bcc7eb25668da9326791de13df4cd9fd97ece6d713dc422a6c14
|
7
|
+
data.tar.gz: 3844f4f39acbab1b5d62bf771085c723cb98bca680daba8b40b10ec678962f74ed37f5131c7d5d50597a209b4cb0c3f975b0a8970f91d716f48c0e44e08d819a
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Mejuri's ERP integration
|
2
2
|
|
3
|
-
|
3
|
+
The ERP integration gem allows connecting to multiple ERP at the same time and query the data from these ERP's. It's currently only supporting [Fulfil](https://www.fulfil.io).
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -16,8 +16,6 @@ Or run the following command to add `ErpIntegration` to your Gemfile:
|
|
16
16
|
$ bundle add erp_integration
|
17
17
|
```
|
18
18
|
|
19
|
-
TODO: Write installation instructions here for the Github package registry.
|
20
|
-
|
21
19
|
## Usage
|
22
20
|
|
23
21
|
### Configuration
|
@@ -32,20 +30,15 @@ ErpIntegration.configure do |config|
|
|
32
30
|
end
|
33
31
|
```
|
34
32
|
|
35
|
-
###
|
36
|
-
|
37
|
-
After configuring the gem, one can easily query all the available ERP resources from the connected third-parties.
|
33
|
+
### Supported Query Methods
|
38
34
|
|
39
|
-
|
40
|
-
$ ErpIntegration::SalesOrder.where(reference: 'MT1000SKX')
|
41
|
-
=> #<ErpIntegration::Fulfil::Collection @items=[<ErpIntegration::SalesOrder @id=100 />] />
|
42
|
-
```
|
35
|
+
After configuring the gem, one can easily query all the available ERP resources from the connected third-parties. In all cases, the API will return a collection of resources.
|
43
36
|
|
44
|
-
|
37
|
+
> **NOTE**: If you need to lookup an individual resource take a look at the "Supported finder methods" section.
|
45
38
|
|
46
39
|
```ruby
|
47
|
-
$ ErpIntegration::SalesOrder.
|
48
|
-
=>
|
40
|
+
$ ErpIntegration::SalesOrder.where(reference: 'MT1000SKX')
|
41
|
+
=> [<ErpIntegration::SalesOrder @id=100 />]
|
49
42
|
```
|
50
43
|
|
51
44
|
There are also other type of `where` queries available:
|
@@ -55,50 +48,81 @@ There are also other type of `where` queries available:
|
|
55
48
|
- `where_in` for inclusion queries.
|
56
49
|
- `where_not_in` for exclusion queries.
|
57
50
|
|
58
|
-
|
51
|
+
### Supported Finder Methods
|
59
52
|
|
60
|
-
|
53
|
+
The __Query Methods__ allow you to lookup a list of resources. The __Finder Methods__ allow you to lookup **an individual resource** from the API.
|
61
54
|
|
62
|
-
|
55
|
+
- `#find` looks up a resource by id and raises `ErpIntegration::ResourceNotFound` when no result is found.
|
56
|
+
- `#find_by` looks up a resource by a given set of query methods and returns `nil` when no result is found.
|
57
|
+
- `#find_by!` looks up a resource by a given set of query methods and raises `ErpIntegration::ResourceNotFound` when no result is found.
|
63
58
|
|
64
|
-
|
59
|
+
A difference between the query methods and the finder methods is the way it's executed. The finder methods are executed directly after they're called. The query methods will be lazily executed.
|
65
60
|
|
66
|
-
|
61
|
+
```ruby
|
62
|
+
$ ErpIntegration::SalesOrder.find(100)
|
63
|
+
# => #<ErpIntegration::SalesOrder @id=100 />
|
67
64
|
|
68
|
-
|
65
|
+
$ ErpIntegration::SalesOrder.find_by(code: "MT100")
|
66
|
+
# => #<ErpIntegration::SalesOrder @id=100 />
|
69
67
|
|
70
|
-
|
68
|
+
$ ErpIntegration::SalesOrder.find_by!(code: "MT100")
|
69
|
+
# => #<ErpIntegration::SalesOrder @id=100 />
|
70
|
+
```
|
71
71
|
|
72
|
-
|
72
|
+
### Supported Selection Methods
|
73
73
|
|
74
|
-
|
74
|
+
By default, only the `id` will be added to ERP resources. However, one can use the `select` method to include more fields.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
$ ErpIntegration::SalesOrder.select(:id, :reference).find_by(reference: 'MT1000SKX')
|
78
|
+
# => <ErpIntegration::SalesOrder @id=100 @reference=MT1000SKX />
|
79
|
+
```
|
80
|
+
|
81
|
+
## Development
|
75
82
|
|
76
|
-
|
83
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
84
|
+
|
85
|
+
### Releasing
|
77
86
|
|
78
|
-
|
87
|
+
**Prerequisites**
|
79
88
|
|
80
89
|
To be able to publish a new release, you'll need to set up a Rubygems account.
|
81
90
|
|
82
91
|
> To begin, you’ll need to create an account on RubyGems.org. Visit the sign up page and supply an email address that you control, a handle (username) and a password.
|
83
92
|
>
|
84
93
|
> After creating the account, use your email and password when pushing the gem. (RubyGems saves the credentials in ~/.gem/credentials for you so you only need to log in once.)
|
85
|
-
>
|
94
|
+
> [Publishing to RubyGems.org](https://guides.rubygems.org/publishing/)
|
86
95
|
|
87
|
-
It's important to note that you'll need the right privileges to publish the gem. Ask @germansvriz to add you as a gem owner.
|
96
|
+
It's important to note that you'll need the right privileges to publish the gem. Ask [@germansvriz](https://github.com/germansvriz) or [@stefanvermaas](https://github.com/stefanvermaas) to add you as a gem owner.
|
88
97
|
|
89
|
-
|
98
|
+
**Publish a new version**
|
90
99
|
|
91
|
-
1
|
92
|
-
```shell
|
93
|
-
$ bin/prerelease 0.0.1
|
94
|
-
```
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
100
|
+
1. Run the prerelease script
|
101
|
+
```shell
|
102
|
+
$ bin/prerelease 0.0.1
|
103
|
+
```
|
104
|
+
|
105
|
+
2. Create Pull Request
|
106
|
+
|
107
|
+
3. Merge it to main
|
108
|
+
|
109
|
+
4. Run Release script
|
110
|
+
```shell
|
111
|
+
$ bin/release 0.0.1
|
112
|
+
```
|
101
113
|
|
102
114
|
We're following [semver](https://semver.org/) for the release process of this gem. Make sure to apply the correct semver version for a new release.
|
103
115
|
|
104
116
|
> **NOTE**: You don't have to add a `v` to the version you want to release. The release script will handle that for you.
|
117
|
+
|
118
|
+
## Contributing
|
119
|
+
|
120
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/mejuri-inc/erp_integration. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/mejuri-inc/erp_integration/blob/main/CODE_OF_CONDUCT.md).
|
121
|
+
|
122
|
+
## License
|
123
|
+
|
124
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
125
|
+
|
126
|
+
## Code of Conduct
|
127
|
+
|
128
|
+
Everyone interacting in the ErpIntegration project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mejuri-inc/erp_integration/blob/main/CODE_OF_CONDUCT.md).
|
@@ -37,6 +37,16 @@ module ErpIntegration
|
|
37
37
|
# @return [Symbol] The configured adapter for the bill_of_material.
|
38
38
|
attr_writer :bill_of_material_output_adapter
|
39
39
|
|
40
|
+
# Allows configuring an adapter for the `CustomerShipment` resource. When
|
41
|
+
# none is configured, it will default to Fulfil.
|
42
|
+
# @return [Symbol] The configured adapter for the customer shipment.
|
43
|
+
attr_writer :customer_shipment_adapter
|
44
|
+
|
45
|
+
# Allows configuring an adapter for the `CustomerShipmentReturn` resource. When
|
46
|
+
# none is configured, it will default to Fulfil.
|
47
|
+
# @return [Symbol] The configured adapter for the customer shipment.
|
48
|
+
attr_writer :customer_shipment_return_adapter
|
49
|
+
|
40
50
|
# Allows configuring an adapter for the `Product` resource. When none is
|
41
51
|
# configured, it will default to Fulfil.
|
42
52
|
# @return [Symbol] The configured adapter for the products.
|
@@ -100,6 +110,14 @@ module ErpIntegration
|
|
100
110
|
@bill_of_material_output_adapter || :fulfil
|
101
111
|
end
|
102
112
|
|
113
|
+
def customer_shipment_adapter
|
114
|
+
@customer_shipment_adapter || :fulfil
|
115
|
+
end
|
116
|
+
|
117
|
+
def customer_shipment_return_adapter
|
118
|
+
@customer_shipment_return_adapter || :fulfil
|
119
|
+
end
|
120
|
+
|
103
121
|
def product_adapter
|
104
122
|
@product_adapter || :fulfil
|
105
123
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
# The `ErpIntegration::CustomerShipment` exposes an uniformed API for interaction with
|
5
|
+
# third-party ERP vendors.
|
6
|
+
class CustomerShipment < Resource
|
7
|
+
attr_accessor :acknowledged_by_3pl_at, :aes_itn, :assigned_by, :assigned_time, :attachments,
|
8
|
+
:available_carrier_services, :avg_cycle_time, :avg_cycle_time_cache, :carrier,
|
9
|
+
:carrier_billing_account, :carrier_cost_method, :carrier_duties_account,
|
10
|
+
:carrier_service, :channel_carrier_service_code, :channel_logo_url, :channels,
|
11
|
+
:checklists, :company, :consumable_moves, :consumables_cost, :consumables_cost_cache,
|
12
|
+
:contact_categories, :contents_explanation, :contents_type, :cost, :cost_currency,
|
13
|
+
:cost_currency_digits, :cost_invoice_line, :create_date, :create_return_label, :create_uid,
|
14
|
+
:customer, :customer_location, :customs_items, :default_box_type, :delivery_address,
|
15
|
+
:delivery_address_datetime, :delivery_mode, :done_by, :duties_tax_id, :duties_tax_id_type,
|
16
|
+
:eel_pfc, :effective_date, :eori_number, :fedex_saturday_delivery, :full_delivery_address,
|
17
|
+
:gift_message, :has_gift_message, :hold_reason, :id, :incoterm, :insurance_amount, :inventory_moves,
|
18
|
+
:invoices, :is_international_shipping, :is_shippo, :last_modification, :license_plates, :messages,
|
19
|
+
:metadata, :moves, :non_delivery_option, :number, :on_hold, :on_hold_until, :order_confirmation_time,
|
20
|
+
:order_numbers, :origins, :outgoing_moves, :packages, :packed_at, :packed_by, :packed_date, :packer,
|
21
|
+
:payment_status, :payment_transactions, :picked_at, :picked_date, :picker, :picking_started_at,
|
22
|
+
:picking_status, :planned_date, :planned_datetime, :planned_time, :priority, :private_notes,
|
23
|
+
:productions, :public_notes, :rec_blurb, :rec_name, :reference, :request_confirmation,
|
24
|
+
:requested_delivery_date, :requested_shipping_service, :require_customs, :root_packages, :sale_date,
|
25
|
+
:sales, :sent_to_3pl_at, :shipped_at, :shipper, :shipping_batch, :shipping_instructions,
|
26
|
+
:shipping_label_date, :shipping_label_printed, :shipping_manifest, :sscc_code, :state, :tax_id,
|
27
|
+
:total_amount_ccy, :total_cost, :total_customs_value, :total_item_cost_ccy, :total_quantity, :tpl,
|
28
|
+
:tpl_status, :tracking_export_status, :tracking_number, :tracking_number_blurb, :tsv,
|
29
|
+
:ups_saturday_delivery, :warehouse, :warehouse_output, :warehouse_storage, :weight, :weight_digits,
|
30
|
+
:weight_uom, :weight_uom_symbol, :write_date, :write_uid
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
# The `ErpIntegration::CustomerShipmentReturn` exposes an uniformed API for interaction with
|
5
|
+
# third-party ERP vendors.
|
6
|
+
class CustomerShipmentReturn < Resource
|
7
|
+
attr_accessor :aes_itn, :attachments, :available_carrier_services, :carrier,
|
8
|
+
:carrier_billing_account, :carrier_cost_method, :carrier_duties_account,
|
9
|
+
:carrier_service, :channels, :company, :contents_explanation, :contents_type,
|
10
|
+
:cost, :cost_currency, :cost_currency_digits, :create_date, :create_uid,
|
11
|
+
:customer, :customer_location, :customs_items, :delivery_address, :delivery_mode,
|
12
|
+
:done_by, :duties_tax_id, :duties_tax_id_type, :eel_pfc, :effective_date,
|
13
|
+
:eori_number, :id, :incoming_moves, :inventory_moves, :is_international_shipping,
|
14
|
+
:is_shippo, :last_modification, :license_plates, :messages, :metadata, :moves,
|
15
|
+
:origins, :number, :packages, :planned_date, :private_notes, :public_notes, :putaway_by,
|
16
|
+
:rec_blurb, :rec_name, :received_by, :reference, :require_customs, :root_packages, :sales,
|
17
|
+
:sent_to_3pl_at, :shipping_instructions, :shipping_manifest, :sscc_code, :state,
|
18
|
+
:total_customs_value, :tpl_status, :tracking_number, :tsv, :warehouse, :warehouse_input,
|
19
|
+
:warehouse_storage, :warehouse_type, :weight, :weight_digits, :weight_uom,
|
20
|
+
:weight_uom_symbol, :write_date, :write_uid
|
21
|
+
end
|
22
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'finder_methods'
|
4
|
+
require_relative 'persistence'
|
4
5
|
require_relative 'query_methods'
|
5
6
|
|
6
7
|
module ErpIntegration
|
@@ -8,6 +9,7 @@ module ErpIntegration
|
|
8
9
|
class ApiResource
|
9
10
|
include Enumerable
|
10
11
|
include FinderMethods
|
12
|
+
include Persistence
|
11
13
|
include QueryMethods
|
12
14
|
|
13
15
|
attr_accessor :resource_klass
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
module Fulfil
|
5
|
+
module Persistence
|
6
|
+
# Allows creating new resources in Fulfil.
|
7
|
+
#
|
8
|
+
# @param attributes [Hash] A list of attributes for the new resource.
|
9
|
+
# @return [Array|Hash] The response from the API
|
10
|
+
def create(attributes)
|
11
|
+
client
|
12
|
+
.post("model/#{model_name}", normalize_attributes(attributes))
|
13
|
+
.map { |new_record_id| attributes.merge!(id: new_record_id) }
|
14
|
+
.first
|
15
|
+
rescue ErpIntegration::HttpError::BadRequest => e
|
16
|
+
[attributes, [extract_error_message(e)]]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Updates the resource with the given attributes.
|
20
|
+
#
|
21
|
+
# @param resource_id [Integer] The ID of the resource.
|
22
|
+
# @param attributes [Hash] A list of attributes to update for the resource.
|
23
|
+
# @return [Array|Hash] The response from the API
|
24
|
+
def update(resource_id, attributes)
|
25
|
+
client.put("model/#{model_name}/#{resource_id}", attributes)
|
26
|
+
rescue ErpIntegration::HttpError::BadRequest => e
|
27
|
+
[attributes, [extract_error_message(e)]]
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Fulfil returns a 400 status code (e.g. Bad Request) with the error message
|
33
|
+
# in the body. We're using the exception to extract the error message in the
|
34
|
+
# body of the original response from Fulfil.
|
35
|
+
#
|
36
|
+
# @param error [ErpIntegration::HttpError::BadRequest] The exception raised by our middleware.
|
37
|
+
# @return [String] The error message by Fulfil.
|
38
|
+
def extract_error_message(error)
|
39
|
+
JSON.parse(error.response[:body]).fetch('message')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Fulfil always expects an array of attributes. That way, we could also create
|
43
|
+
# a whole bunch of objects all at once. We don't support creating multiple records
|
44
|
+
# yet as it's not needed yet. However, we do need to normalize the attributes we're
|
45
|
+
# passing to the Fulfil API.
|
46
|
+
#
|
47
|
+
# @param attributes [Hash|Array<Hash>] The attributes for the new resource.
|
48
|
+
# @return [Array<Hash>] The normalized attributes.
|
49
|
+
def normalize_attributes(attributes)
|
50
|
+
attrs = attributes.is_a?(Array) ? attributes : [attributes]
|
51
|
+
attrs.compact
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -7,6 +7,45 @@ module ErpIntegration
|
|
7
7
|
module Resources
|
8
8
|
class SalesOrderLine < ApiResource
|
9
9
|
self.model_name = 'sale.line'
|
10
|
+
# Allows cancelling the entire sales order line in Fulfil.
|
11
|
+
# @param id [Integer|String] The ID of the to be cancelled order line.
|
12
|
+
# @return [boolean] Whether the sales order line was cancelled successfully or not.
|
13
|
+
def cancel(id)
|
14
|
+
client.put("model/sale.line/#{id}/cancel")
|
15
|
+
true
|
16
|
+
rescue ErpIntegration::HttpError::BadRequest
|
17
|
+
false
|
18
|
+
# Workaround: Fulfil api does not return a json when status code is 200 (a.k.a. "Ok")
|
19
|
+
# and faraday is having an error when trying to parse it. Let's skip the parse error
|
20
|
+
# and move on.
|
21
|
+
rescue Faraday::ParsingError
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
# Updates the sales order line quantity of canceled and non canceled items
|
26
|
+
# @param sales_channel [Integer] Sales channel id
|
27
|
+
# @param channel_identifier [String]
|
28
|
+
# @param sku [String]
|
29
|
+
# @param quantity [Integer] The total quantity (canceled + not canceled)
|
30
|
+
# Should be more or equal than quantity_canceled but the above criteria is suggested
|
31
|
+
# @param quantity_canceled [Integer] the total quantity of canceled items (including new ones)
|
32
|
+
# @return [boolean] Whether the sales order line was changed successfully or not.
|
33
|
+
def adjust_quantity(sales_channel, channel_identifier,
|
34
|
+
sku, quantity, quantity_canceled)
|
35
|
+
options = [{
|
36
|
+
"channel_identifier": channel_identifier,
|
37
|
+
"sale_lines":
|
38
|
+
[{
|
39
|
+
"sku": sku,
|
40
|
+
"quantity": quantity,
|
41
|
+
"quantity_canceled": quantity_canceled
|
42
|
+
}]
|
43
|
+
}]
|
44
|
+
client.put("model/sale.channel/#{sales_channel}/create_order", options)
|
45
|
+
true
|
46
|
+
rescue ErpIntegration::HttpError::BadRequest
|
47
|
+
false
|
48
|
+
end
|
10
49
|
end
|
11
50
|
end
|
12
51
|
end
|
@@ -29,11 +29,20 @@ module ErpIntegration
|
|
29
29
|
# 5. Create a new adapter class prefixed with the adapter's name
|
30
30
|
# (e.g. `FulfilOrder` for the `Order` resource in the `lib/erp_integration/orders` folder).
|
31
31
|
class Resource
|
32
|
+
include Resources::Validations
|
33
|
+
include Resources::Persistence
|
34
|
+
|
32
35
|
attr_accessor :raw_api_response
|
33
36
|
|
34
37
|
def initialize(attributes = {})
|
35
38
|
@raw_api_response = attributes
|
39
|
+
assign_attributes(attributes)
|
40
|
+
end
|
36
41
|
|
42
|
+
# Allows assigning attributes to an resource instance.
|
43
|
+
# @param attributes [Hash] A list of attributes for the resource.
|
44
|
+
# @return [Hash] The list of assigned attributes.
|
45
|
+
def assign_attributes(attributes = {})
|
37
46
|
attributes.each_pair do |name, value|
|
38
47
|
public_send(:"#{name}=", value) if respond_to?(:"#{name}=")
|
39
48
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
module Resources
|
5
|
+
# The `ErpIntegration::Resources::Errors` expose a clean, simple API to manage
|
6
|
+
# and display error messages for any `ErpIntegration::Resource` instance.
|
7
|
+
class Errors
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
extend Forwardable
|
11
|
+
def_delegators :@errors, :any?, :blank?, :clear, :count, :empty?, :uniq!, :size
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@errors = []
|
15
|
+
end
|
16
|
+
|
17
|
+
# Allows adding new error messages to the `ErpIntegration::Resource`.
|
18
|
+
# @param message [String] An (internal/external) error message.
|
19
|
+
# @return [String] The given error message.
|
20
|
+
def add(message)
|
21
|
+
raise ErpIntegration::Error, 'Use a simple string as an error message' unless message.is_a?(String)
|
22
|
+
|
23
|
+
@errors << message
|
24
|
+
message
|
25
|
+
end
|
26
|
+
|
27
|
+
def each(&block)
|
28
|
+
@errors.each(&block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
module Resources
|
5
|
+
module Persistence
|
6
|
+
def self.included(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Creates a new resource in the ERP.
|
12
|
+
# @param attributes [Hash] A list of attributes for the new resource.
|
13
|
+
# @return [ErpIntegration::Resource] The (to be) created resource.
|
14
|
+
def create(attributes)
|
15
|
+
attrs, error_messages = adapter.create(**attributes)
|
16
|
+
|
17
|
+
new_resource = new(attrs)
|
18
|
+
new_resource.validate_with(error_messages)
|
19
|
+
new_resource
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Determines whether a `ErpIntegration::Resource` is considered to be persisted.
|
24
|
+
# @return [Boolean] Whether it's persisted or not.
|
25
|
+
def persisted?
|
26
|
+
!id.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Update an resource in the ERP.
|
30
|
+
# @param attributes [Hash] A list of attributes to update.
|
31
|
+
# @return [Boolean] Whether the update action was succcesful or not.
|
32
|
+
def update(attributes)
|
33
|
+
attrs, error_messages = self.class.adapter.update(id, **attributes)
|
34
|
+
|
35
|
+
assign_attributes(attrs)
|
36
|
+
validate_with(error_messages)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ErpIntegration
|
4
|
+
module Resources
|
5
|
+
module Validations
|
6
|
+
# Exposes all errors related to an `ErpIntegration::Resource`.
|
7
|
+
#
|
8
|
+
# @return [ErpIntegration::Resources::Errors] Encapsulation of all error messages.
|
9
|
+
def errors
|
10
|
+
@errors ||= Resources::Errors.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Checks whether an resource is considered valid or not.
|
14
|
+
#
|
15
|
+
# @return [Boolean] Is the resource valid according to the ERP?
|
16
|
+
def valid?
|
17
|
+
errors.none?
|
18
|
+
end
|
19
|
+
|
20
|
+
# Validates the resource by checking the given error messages.
|
21
|
+
#
|
22
|
+
# @param error_messages [Array] A list of error messages.
|
23
|
+
# @return [Boolean] Whether the resource is valid or not.
|
24
|
+
def validate_with(*error_messages)
|
25
|
+
errors.clear
|
26
|
+
|
27
|
+
error_messages.flatten.compact.each do |error_message|
|
28
|
+
errors.add(error_message)
|
29
|
+
end
|
30
|
+
|
31
|
+
valid?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -12,5 +12,13 @@ module ErpIntegration
|
|
12
12
|
:quantity_reserved, :quantity_shipped, :return_reason, :sale,
|
13
13
|
:sequence, :shipping_date, :taxes, :type, :warehouse, :write_date,
|
14
14
|
:write_uid
|
15
|
+
|
16
|
+
def cancel(id)
|
17
|
+
self.class.adapter.cancel(id)
|
18
|
+
end
|
19
|
+
|
20
|
+
def adjust_quantity(sales_channel, channel_identifier, sku, quantity, quantity_canceled)
|
21
|
+
self.class.adapter.adjust_quantity(sales_channel, channel_identifier, sku, quantity, quantity_canceled)
|
22
|
+
end
|
15
23
|
end
|
16
24
|
end
|
data/lib/erp_integration.rb
CHANGED
@@ -23,6 +23,8 @@ module ErpIntegration
|
|
23
23
|
autoload :BillOfMaterial, 'erp_integration/bill_of_material'
|
24
24
|
autoload :BillOfMaterialInput, 'erp_integration/bill_of_material_input'
|
25
25
|
autoload :BillOfMaterialOutput, 'erp_integration/bill_of_material_output'
|
26
|
+
autoload :CustomerShipment, 'erp_integration/customer_shipment'
|
27
|
+
autoload :CustomerShipmentReturn, 'erp_integration/customer_shipment_return'
|
26
28
|
autoload :Product, 'erp_integration/product'
|
27
29
|
autoload :ProductionOrder, 'erp_integration/production_order'
|
28
30
|
autoload :PurchaseOrder, 'erp_integration/purchase_order'
|
@@ -33,4 +35,10 @@ module ErpIntegration
|
|
33
35
|
autoload :SalesOrderLine, 'erp_integration/sales_order_line'
|
34
36
|
autoload :StockMove, 'erp_integration/stock_move'
|
35
37
|
autoload :SupplierShipment, 'erp_integration/supplier_shipment'
|
38
|
+
|
39
|
+
module Resources
|
40
|
+
autoload :Errors, 'erp_integration/resources/errors'
|
41
|
+
autoload :Persistence, 'erp_integration/resources/persistence'
|
42
|
+
autoload :Validations, 'erp_integration/resources/validations'
|
43
|
+
end
|
36
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erp_integration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Vermaas
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -224,7 +224,7 @@ dependencies:
|
|
224
224
|
- - '='
|
225
225
|
- !ruby/object:Gem::Version
|
226
226
|
version: 1.19.2
|
227
|
-
description:
|
227
|
+
description:
|
228
228
|
email:
|
229
229
|
- stefan@knowndecimal.com
|
230
230
|
executables: []
|
@@ -263,15 +263,20 @@ files:
|
|
263
263
|
- lib/erp_integration/bill_of_material_input.rb
|
264
264
|
- lib/erp_integration/bill_of_material_output.rb
|
265
265
|
- lib/erp_integration/configuration.rb
|
266
|
+
- lib/erp_integration/customer_shipment.rb
|
267
|
+
- lib/erp_integration/customer_shipment_return.rb
|
266
268
|
- lib/erp_integration/errors.rb
|
267
269
|
- lib/erp_integration/fulfil/api_resource.rb
|
268
270
|
- lib/erp_integration/fulfil/client.rb
|
269
271
|
- lib/erp_integration/fulfil/finder_methods.rb
|
272
|
+
- lib/erp_integration/fulfil/persistence.rb
|
270
273
|
- lib/erp_integration/fulfil/query.rb
|
271
274
|
- lib/erp_integration/fulfil/query_methods.rb
|
272
275
|
- lib/erp_integration/fulfil/resources/bill_of_material.rb
|
273
276
|
- lib/erp_integration/fulfil/resources/bill_of_material_input.rb
|
274
277
|
- lib/erp_integration/fulfil/resources/bill_of_material_output.rb
|
278
|
+
- lib/erp_integration/fulfil/resources/customer_shipment.rb
|
279
|
+
- lib/erp_integration/fulfil/resources/customer_shipment_return.rb
|
275
280
|
- lib/erp_integration/fulfil/resources/product.rb
|
276
281
|
- lib/erp_integration/fulfil/resources/production_order.rb
|
277
282
|
- lib/erp_integration/fulfil/resources/purchase_order.rb
|
@@ -289,6 +294,9 @@ files:
|
|
289
294
|
- lib/erp_integration/purchase_order_line.rb
|
290
295
|
- lib/erp_integration/purchase_request.rb
|
291
296
|
- lib/erp_integration/resource.rb
|
297
|
+
- lib/erp_integration/resources/errors.rb
|
298
|
+
- lib/erp_integration/resources/persistence.rb
|
299
|
+
- lib/erp_integration/resources/validations.rb
|
292
300
|
- lib/erp_integration/sales_order.rb
|
293
301
|
- lib/erp_integration/sales_order_line.rb
|
294
302
|
- lib/erp_integration/stock_move.rb
|
@@ -302,7 +310,7 @@ metadata:
|
|
302
310
|
homepage_uri: https://www.github.com/mejuri-inc/erp-integration
|
303
311
|
source_code_uri: https://www.github.com/mejuri-inc/erp-integration
|
304
312
|
changelog_uri: https://www.github.com/mejuri-inc/erp-integration/blob/main/CHANGELOG.md
|
305
|
-
post_install_message:
|
313
|
+
post_install_message:
|
306
314
|
rdoc_options: []
|
307
315
|
require_paths:
|
308
316
|
- lib
|
@@ -317,8 +325,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
317
325
|
- !ruby/object:Gem::Version
|
318
326
|
version: '0'
|
319
327
|
requirements: []
|
320
|
-
rubygems_version: 3.
|
321
|
-
signing_key:
|
328
|
+
rubygems_version: 3.0.3
|
329
|
+
signing_key:
|
322
330
|
specification_version: 4
|
323
331
|
summary: Connects Mejuri with third-party ERP vendors
|
324
332
|
test_files: []
|