moloni 0.5.0 → 0.5.1

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: 0fd2b46790ffa005a63b070cd61e841afb66f72ecacb6d0616d2ed95af2a19e4
4
- data.tar.gz: 6461230850e14c022010e9021948b20789958c2f3ee74cb3ba834713240e480c
3
+ metadata.gz: f30248a3261946fc4dd7b032d350e7200ccd0aacedb2716b081c6558555a3c4c
4
+ data.tar.gz: 77f95dd212fe05082c51f175480232a62a7b6cc2fa1389be2de9bb3844d46844
5
5
  SHA512:
6
- metadata.gz: be6798d96a26ebde2d5f714d8216cea066797af66e4e10d23519200bf26fa2af0c99ca005abaf6241ccddbbfea0065edb767e86f80fc6cede7a33e7dde51db78
7
- data.tar.gz: f6d873d8bfb6045d3dccbdda1873761fa3c955b1ed35ef8684f90f152adc970039008f74ee7e0cfa0bb5f05e44872a1d5d05010fbcda05f904e84193f9b984ab
6
+ metadata.gz: 50f8d1aa864564bcfb6ed0fc6d73605be3f016b1a2cacb13c0b6089ffeaa9e55ee87d901c07a2c1396d7ac11426b90fec99110dd3efb25982d317c342b562444
7
+ data.tar.gz: cd10ee2f20c76c784bec31ebb3f5b17a4a3699a3855677f3d7889309caf1ee04ca8a48830c74c2d5c5f27e0f8278e468f532673c1b730417dc9fdc9e3145ca2a
data/AGENTS.md CHANGED
@@ -39,3 +39,9 @@ bundle exec rubocop # lint
39
39
  - `Tax#iva_normal`, `#iva_intermedio`, `#iva_reduzido` still exist with hardcoded IDs.
40
40
  - `Company.all` (the broken GET version) was removed; use `Company.getAll` via dynamic dispatch.
41
41
  - `User.me` and `Printer.all` remain as explicit custom methods.
42
+
43
+ ## Pagination (Product, 0.5)
44
+ - `Product.each_page(method, args, qty: 50) { |page| ... }` — yields full page arrays, stops when `page.length < qty`. Returns `Enumerator` without a block.
45
+ - `Product.paginate(method, args, qty: 50) { |item| ... }` — yields individual items across all pages. Returns `Enumerator` without a block.
46
+ - Works with any method that supports `offset`/`qty` params (getAll, getByEAN, getByReference, getByName, getBySearch, getModifiedSince).
47
+ - Detection of last page: result array is shorter than requested `qty`.
data/CHANGELOG.md ADDED
@@ -0,0 +1,65 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.5.1] — 2026-05-20
8
+
9
+ ### Added
10
+ - `Product.each_page(method, args, qty: 50)` — yields full page arrays, stops when `page.length < qty`. Returns `Enumerator` without a block.
11
+ - `Product.paginate(method, args, qty: 50)` — yields individual items across all pages. Returns `Enumerator` without a block.
12
+ - Works with any method supporting `offset`/`qty` params: `getAll`, `getByEAN`, `getByReference`, `getByName`, `getBySearch`, `getModifiedSince`.
13
+
14
+ ## [0.5.0] — 2026-05-11
15
+
16
+ ### Changed
17
+ - **Ruby requirement:** Now requires Ruby 3.2 or later.
18
+ - **HTTP method:** All API calls now use `POST` (previously some reads used `GET`).
19
+ - **Auth URL fix:** `Moloni::Auth.auth_url` now correctly points to `https://www.moloni.pt/ac/root/oauth/`.
20
+ - **Multi-json removed:** Replaced `multi_json` with standard library `JSON`.
21
+ - Updated dependencies (Faraday 2.x, Addressable 2.x, Sinatra 4.x).
22
+ - Token auto-refresh with 5-minute safety margin before expiry.
23
+
24
+ ### Added
25
+ - Backward-compatible `all`, `find`, `count`, `create`, `delete` aliases on `BaseModel`.
26
+ - `Product.searchByName` and `Product.search_by_name` aliases.
27
+
28
+ ### Removed
29
+ - `Company.all` (broken GET version). Use `Company.getAll` via dynamic dispatch.
30
+
31
+ ## [0.4.0] — 2024-01-29
32
+
33
+ ### Fixed
34
+ - Fixed args input in all methods.
35
+
36
+ ## [0.3.x] — 2021
37
+
38
+ ### Added
39
+ - Simplified invoice model.
40
+ - Invoice receipts model.
41
+ - Customer update support.
42
+ - Product search (`getByName`, `getByReference`).
43
+ - Customer `getByNumber`, `getByEmail`.
44
+ - Language shortcuts (`pt`, `en`, `es`).
45
+ - Payment method and maturity date helpers.
46
+
47
+ ### Changed
48
+ - Updated Faraday dependency versions.
49
+
50
+ ## [0.2.x] — 2020-12
51
+
52
+ ### Added
53
+ - Initial model support: Company, User, Subscription, Printer, Tax, Country.
54
+ - Customer model with `find_by_vat`, `create` (with default params).
55
+ - Product, Document, DocumentSet, ProductCategory, ProductStock models.
56
+ - Invoice creation with products, taxes, document sets.
57
+ - OAuth 2.0 client token retrieval flow.
58
+
59
+ ## [0.1.0] — 2020-12-11
60
+
61
+ ### Added
62
+ - Initial release.
63
+ - Faraday HTTP client pointing to `https://api.moloni.pt/v1/`.
64
+ - Basic OAuth configuration support.
65
+ - `base_model.rb` with POST-only requests and `human_errors=true`.
data/MOLONI_API_DOC.md CHANGED
@@ -254,6 +254,35 @@ Manage products, categories, stock, and pricing.
254
254
 
255
255
  Typical methods: `getAll`, `getOne`, `insert`, `update`, `delete`.
256
256
 
257
+ #### Pagination
258
+
259
+ The following product methods support `offset` and `qty` parameters for server-side pagination:
260
+
261
+ | Method | Parameters |
262
+ |--------|-----------|
263
+ | `getAll` | `offset`, `qty` |
264
+ | `getByName` | `name`, `offset`, `qty` |
265
+ | `getBySearch` | `search`, `offset`, `qty` |
266
+ | `getByEAN` | `ean`, `offset`, `qty` |
267
+ | `getByReference` | `reference`, `offset`, `qty` |
268
+ | `getModifiedSince` | `lastmodified`, `offset`, `qty` |
269
+
270
+ - **`offset`** — integer, default `0`. Number of records to skip.
271
+ - **`qty`** — integer, default `50`, maximum `50`. Number of records per page.
272
+
273
+ The gem provides two helper methods for iterating paginated results:
274
+
275
+ ```ruby
276
+ # each_page — yields full page arrays, stops when page < qty
277
+ Moloni::Product.each_page(:get_all, qty: 50) { |page| ... }
278
+
279
+ # paginate — yields individual items across all pages
280
+ Moloni::Product.paginate(:get_all, qty: 50) { |item| ... }
281
+
282
+ # Both return Enumerator when called without a block
283
+ Moloni::Product.paginate(:get_all).each { |item| ... }
284
+ ```
285
+
257
286
  ---
258
287
 
259
288
  ### 6.3 Documents
data/README.md CHANGED
@@ -89,6 +89,31 @@ Moloni::Product.get_by_reference(reference: 'ABC-123')
89
89
  Moloni::Invoice.getByNumber(number: 'FT 2025/001')
90
90
  ```
91
91
 
92
+ ### Pagination (Product)
93
+
94
+ Methods that support the Moloni `offset`/`qty` parameters (getAll, getByEAN, getByReference, getByName, getBySearch, getModifiedSince) have built-in helpers for iterating through all results:
95
+
96
+ ```ruby
97
+ # Layer 1 — yields full page arrays
98
+ Moloni::Product.each_page(:get_all, qty: 50) do |page|
99
+ page.each { |product| puts product[:name] }
100
+ end
101
+
102
+ # Layer 2 — yields individual items across all pages
103
+ Moloni::Product.paginate(:get_all, qty: 50) do |product|
104
+ puts product[:name]
105
+ end
106
+
107
+ # Both return an Enumerator when called without a block
108
+ products = Moloni::Product.paginate(:get_all).to_a
109
+ pages = Moloni::Product.each_page(:get_all).to_a
110
+
111
+ # Snake_case methods and extra args are supported
112
+ Moloni::Product.paginate(:get_by_name, { name: 'Widget' }, qty: 25) { |p| ... }
113
+ ```
114
+
115
+ Pagination stops automatically when a page has fewer items than the requested `qty`.
116
+
92
117
  ### Customers
93
118
 
94
119
  ```ruby
@@ -6,6 +6,30 @@ module Moloni
6
6
  class Product < BaseModel
7
7
  @intermediate_path = 'products/'
8
8
 
9
+ def self.each_page(method, args = nil, qty: 50, &block)
10
+ return enum_for(:each_page, method, args, qty:) unless block
11
+
12
+ args ||= {}
13
+ offset = 0
14
+
15
+ loop do
16
+ page = send(method, args.merge(offset:, qty:))
17
+ break unless page.is_a?(Array)
18
+ break if page.empty?
19
+
20
+ yield page
21
+ break if page.length < qty
22
+
23
+ offset += qty
24
+ end
25
+ end
26
+
27
+ def self.paginate(method, args = nil, qty: 50, &block)
28
+ return enum_for(:paginate, method, args, qty:) unless block
29
+
30
+ each_page(method, args, qty:) { |page| page.each(&block) }
31
+ end
32
+
9
33
  # Backward-compatible alias (v0.4 API name)
10
34
  # rubocop:disable Naming/MethodName
11
35
  def self.searchByName(args)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moloni
4
- VERSION = '0.5.0'
4
+ VERSION = '0.5.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moloni
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Pinto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-11 00:00:00.000000000 Z
11
+ date: 2026-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -207,6 +207,7 @@ files:
207
207
  - ".rubocop.yml"
208
208
  - ".travis.yml"
209
209
  - AGENTS.md
210
+ - CHANGELOG.md
210
211
  - Gemfile
211
212
  - Gemfile.lock
212
213
  - LICENSE.txt