Class: Belpost::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/belpost/client.rb

Overview

Main client class for interacting with the BelPost API.

Instance Method Summary collapse

Constructor Details

#initialize(logger: Logger.new($stdout)) ⇒ Client

Initializes a new instance of the Client.

Raises:



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/belpost/client.rb', line 21

def initialize(logger: Logger.new($stdout))
  @config = Belpost.configuration
  raise ConfigurationError, "JWT token is required" if @config.jwt_token.nil?

  @api_service = ApiService.new(
    base_url: @config.base_url,
    jwt_token: @config.jwt_token,
    timeout: @config.timeout,
    logger: logger
  )
end

Instance Method Details

#commit_batch(batch_id) ⇒ Hash

Commits a batch mailing by its ID, changing status from “uncommitted” to “committed”.

This method can only commit a batch that is currently uncommitted, has items and includes contents if the batch has “is_partial_receipt” flag set to true.

Parameters:

  • batch_id (Integer)

    The ID of the batch to commit

Returns:

  • (Hash)

    The committed batch data with updated status

Raises:



273
274
275
276
277
278
279
280
# File 'lib/belpost/client.rb', line 273

def commit_batch(batch_id)
  raise ValidationError, "Batch ID must be provided" if batch_id.nil?
  raise ValidationError, "Batch ID must be a positive integer" unless batch_id.is_a?(Integer) && batch_id.positive?

  path = ApiPaths::BATCH_MAILING_COMMIT.gsub(':id', batch_id.to_s)
  response = @api_service.post(path, {})
  response.to_h
end

#create_batch(batch_data) ⇒ Hash

Creates a new batch mailing by sending a POST request to the API.

Parameters:

  • batch_data (Hash)

    The data for the batch mailing.

Returns:

  • (Hash)

    The parsed JSON response from the API.

Raises:



39
40
41
42
43
44
45
46
# File 'lib/belpost/client.rb', line 39

def create_batch(batch_data)
  validation_result = Validation::BatchSchema.new.call(batch_data)
  raise ValidationError, "Invalid batch data: #{validation_result.errors.to_h}" unless validation_result.success?

  batch = Models::Batch.new(batch_data)
  response = @api_service.post(ApiPaths::BATCH_MAILING_LIST, batch.to_h)
  response.to_h
end

#create_batch_items(batch_id, items_data) ⇒ Hash

Creates new items in a batch by sending a POST request to the API.

Parameters:

  • batch_id (Integer)

    The ID of the batch where items should be added.

  • items_data (Hash)

    The data for the batch items to create.

Returns:

  • (Hash)

    The parsed JSON response from the API.

Raises:



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/belpost/client.rb', line 55

def create_batch_items(batch_id, items_data)
  raise ValidationError, "Batch ID must be provided" if batch_id.nil?
  raise ValidationError, "Batch ID must be a positive integer" unless batch_id.is_a?(Integer) && batch_id.positive?

  validation_result = Validation::BatchItemSchema.call(items_data)
  raise ValidationError, "Invalid batch item data: #{validation_result.errors.to_h}" unless validation_result.success?

  batch_item = Models::BatchItem.new(items_data)
  path = ApiPaths::BATCH_MAILING_LIST_ITEM.gsub(':id', batch_id.to_s)
  response = @api_service.post(path, batch_item.to_h)
  response.to_h
end

#create_parcel(parcel_data) ⇒ Hash

Creates a new postal parcel by sending a POST request to the API.

Parameters:

  • parcel_data (Hash)

    The data for the postal parcel.

Returns:

  • (Hash)

    The parsed JSON response from the API.

Raises:



74
75
76
77
78
79
80
81
# File 'lib/belpost/client.rb', line 74

def create_parcel(parcel_data)
  validation_result = Validation::ParcelSchema.call(parcel_data)
  raise ValidationError, "Invalid parcel data: #{validation_result.errors.to_h}" unless validation_result.success?

  parcel = Models::Parcel.new(parcel_data)
  response = @api_service.post(ApiPaths::POSTAL_DELIVERIES, parcel.to_h)
  response.to_h
end

#download_batch_documents(document_id) ⇒ Hash

Downloads batch mailing documents as a ZIP archive.

This method retrieves a ZIP archive containing all documents related to a batch mailing. The response contains binary data that can be saved as a ZIP file.

Parameters:

  • document_id (Integer)

    The ID of the document to download

Returns:

  • (Hash)

    Hash containing binary data, status code and headers

Raises:



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/belpost/client.rb', line 291

def download_batch_documents(document_id)
  raise ValidationError, "Document ID must be provided" if document_id.nil?
  raise ValidationError, "Document ID must be a positive integer" unless document_id.is_a?(Integer) && document_id.positive?

  path = ApiPaths::BATCH_MAILING_DOCUMENTS_DOWNLOAD.gsub(':id', document_id.to_s)
  response = @api_service.get_binary(path)
  
  # Ensure we have the correct content type for a ZIP file
  content_type = response[:headers]["content-type"]&.first
  unless content_type && content_type.include?("application/zip")
    @logger.warn("Expected ZIP file but got content type: #{content_type}")
  end
  
  response
end

#fetch_available_countriesHash

Allows you to get a list of countries to which postal items are sent.

Returns:

  • (Hash)

    The parsed JSON response containing available countries.

Raises:



107
108
109
110
# File 'lib/belpost/client.rb', line 107

def fetch_available_countries
  response = @api_service.get(ApiPaths::POSTAL_DELIVERIES_COUNTRIES)
  response.to_h
end

#fetch_hs_codesArray<Hash>

Fetches the HS codes tree from the API.

Returns:

  • (Array<Hash>)

    The HS codes tree as an array of hashes.

Raises:



87
88
89
90
# File 'lib/belpost/client.rb', line 87

def fetch_hs_codes
  response = @api_service.get(ApiPaths::POSTAL_DELIVERIES_HS_CODES)
  response.to_h
end

#find_address_by_string(address) ⇒ Array<Hash>

Allows you to find an address by a string.

Accepts a string with an address in any form and returns found addresses (up to 50 records). Building numbers should be specified without spaces: “building number”“letter”“building”. The letter should be uppercase, and “building” (or “корп”, “кор”, “к”) should be replaced with “/”. Example: “город Минск улица Автодоровская 3Е корпус 4” should be transformed to “город Минск улица Автодоровская 3Е/4”.

Parameters:

  • address (String)

    The address string to search for.

Returns:

  • (Array<Hash>)

    An array of found addresses with postcode, region, city, street and other information.

Raises:



138
139
140
141
142
143
144
145
146
# File 'lib/belpost/client.rb', line 138

def find_address_by_string(address)
  raise ValidationError, "Address must be filled" if address.nil?
  raise ValidationError, "Address must be a string" unless address.is_a?(String)
  raise ValidationError, "Address must be filled" if address.empty?

  formatted_address = format_address(address)
  response = @api_service.get(ApiPaths::POSTCODES_AUTOCOMPLETE, { search: formatted_address })
  response.to_h
end

#find_addresses_by_postcode(postcode) ⇒ Array<Hash>

Searches for addresses belonging to a specific postal code (postcode).

Parameters:

  • postcode (String)

    The postal code to search for (6 digits)

Returns:

  • (Array<Hash>)

    An array of addresses belonging to the specified postal code

Raises:



154
155
156
157
158
159
160
# File 'lib/belpost/client.rb', line 154

def find_addresses_by_postcode(postcode)
  validation_result = Validation::PostcodeSchema.new.call(postcode: postcode)
  raise ValidationError, "Invalid postcode: #{validation_result.errors.to_h}" unless validation_result.success?

  response = @api_service.get(ApiPaths::GEO_DIRECTORY_ADDRESSES, { postcode: postcode })
  response.to_h
end

#find_batch_by_id(id) ⇒ Hash

Finds a batch by its ID.

Parameters:

  • id (Integer)

    The ID of the batch to find.

Returns:

  • (Hash)

    The batch data if found.

Raises:



118
119
120
121
122
123
124
125
# File 'lib/belpost/client.rb', line 118

def find_batch_by_id(id)
  raise ValidationError, "ID must be provided" if id.nil?
  raise ValidationError, "ID must be a positive integer" unless id.is_a?(Integer) && id.positive?

  path = ApiPaths::BATCH_MAILING_LIST_BY_ID.gsub(':id', id.to_s)
  response = @api_service.get(path)
  response.to_h
end

#generate_batch_blanks(batch_id) ⇒ Hash

Generates address labels for a batch mailing.

This method allows generating address labels for shipments within a batch. Labels can only be generated for batches with the “In processing” status. When this request is made, all address labels for shipments within the batch will be regenerated. Label generation is available if the batch has the “has_documents_label” flag set to false.

If the batch has the “is_partial_receipt” flag set to true and contains shipments with attachments, a PS112e form with attachment descriptions will be included in the response ZIP archive.

If the batch has the “is_partial_receipt” flag set to true and contains shipments without attachments, address labels will not be generated for those shipments. Adding attachments to a shipment is mandatory for generating address labels in this case.

Parameters:

  • batch_id (Integer)

    The ID of the batch to generate labels for

Returns:

  • (Hash)

    The parsed JSON response containing document information

Raises:



255
256
257
258
259
260
261
262
# File 'lib/belpost/client.rb', line 255

def generate_batch_blanks(batch_id)
  raise ValidationError, "Batch ID must be provided" if batch_id.nil?
  raise ValidationError, "Batch ID must be a positive integer" unless batch_id.is_a?(Integer) && batch_id.positive?

  path = ApiPaths::BATCH_MAILING_GENERATE_BLANK.gsub(':id', batch_id.to_s)
  response = @api_service.post(path, {})
  response.to_h
end

#list_batches(page: 1, status: nil, per_page: nil, search: nil) ⇒ Hash

Lists all batches with optional filtering.

Parameters:

  • page (Integer) (defaults to: 1)

    The page number for pagination (optional, default: 1, must be > 0)

  • status (String) (defaults to: nil)

    Filter by status: ‘committed’ or ‘uncommitted’ (optional)

  • per_page (Integer) (defaults to: nil)

    Number of items per page (optional)

  • search (Integer) (defaults to: nil)

    Search by batch number (optional)

Returns:

  • (Hash)

    The parsed JSON response containing batch list with pagination details

Raises:



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/belpost/client.rb', line 198

def list_batches(page: 1, status: nil, per_page: nil, search: nil)
  params = {}

  # Validate page parameter
  if page
    raise ValidationError, "Page must be an integer" unless page.is_a?(Integer)
    raise ValidationError, "Page must be greater than 0" unless page.positive?

    params[:page] = page
  end

  # Validate status parameter
  if status
    unless Models::BatchStatus.valid?(status)
      raise ValidationError, "Status must be 'committed' or 'uncommitted'"
    end

    params[:status] = status
  end

  # Validate per_page parameter
  if per_page
    raise ValidationError, "Per page must be an integer" unless per_page.is_a?(Integer)
    raise ValidationError, "Per page must be positive" unless per_page.positive?

    params[:perPage] = per_page
  end

  # Validate search parameter
  if search
    raise ValidationError, "Search must be an integer" unless search.is_a?(Integer)

    params[:search] = search
  end

  response = @api_service.get(ApiPaths::BATCH_MAILING_LIST, params)
  response.to_h
end

#search_postcode(city:, street:, building: nil, limit: 50) ⇒ Array<Hash>

Searches for postal codes by city, street, and building number.

Parameters:

  • city (String)

    The city name (required)

  • street (String)

    The street name (required)

  • building (String) (defaults to: nil)

    The building number (optional)

  • limit (Integer) (defaults to: 50)

    Maximum number of results (optional, default: 50, range: 1-200)

Returns:

  • (Array<Hash>)

    An array of found addresses with postcode, region, city, street and other information

Raises:



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/belpost/client.rb', line 171

def search_postcode(city:, street:, building: nil, limit: 50)
  raise ValidationError, "City must be filled" if city.nil?
  raise ValidationError, "City must be a string" unless city.is_a?(String)
  raise ValidationError, "City must be filled" if city.empty?
  raise ValidationError, "Street must be filled" if street.nil?
  raise ValidationError, "Street must be a string" unless street.is_a?(String)
  raise ValidationError, "Street must be filled" if street.empty?
  raise ValidationError, "Building must be a string" if building && !building.is_a?(String)
  raise ValidationError, "Limit must be between 1 and 200" if limit < 1 || limit > 200

  params = { city: city, street: street }
  params[:building] = format_building_number(building) if building
  params[:limit] = limit

  response = @api_service.get(ApiPaths::GEO_DIRECTORY_POSTCODE, params)
  response.to_h
end

#translate_batch_status(status) ⇒ String

Translates a batch status code to its Russian translation

Parameters:

  • status (String)

    The status code (‘uncommitted’ or ‘committed’)

Returns:

  • (String)

    The Russian translation or the original status if not found



311
312
313
# File 'lib/belpost/client.rb', line 311

def translate_batch_status(status)
  Models::BatchStatus.translate(status)
end

#validate_postal_delivery(country_code) ⇒ Hash

Fetches validation data for postal deliveries based on the country code.

Parameters:

  • country_code (String)

    The country code (e.g. “BY”, “RU-LEN”).

Returns:

  • (Hash)

    The parsed JSON response containing validation data.

Raises:



97
98
99
100
101
# File 'lib/belpost/client.rb', line 97

def validate_postal_delivery(country_code)
  country_code = country_code.upcase
  response = @api_service.get("#{ApiPaths::POSTAL_DELIVERIES_VALIDATION}/#{country_code}")
  response.to_h
end