Class: Einvoicing::Connect::FR::Pennylane::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/einvoicing/connect/fr/pennylane/client.rb

Constant Summary collapse

BASE_URL =
"https://app.pennylane.com/api/external/v2"
SANDBOX_URL =
"https://sandbox.pennylane.com/api/external/v2"
OAUTH_TOKEN_PATH =
"/oauth/token"
OAUTH_BASE_URL =
"https://app.pennylane.com"
OAUTH_SANDBOX_URL =
"https://sandbox.pennylane.com"

Instance Method Summary collapse

Constructor Details

#initialize(credentials:, sandbox: false) ⇒ Client

Returns a new instance of Client.



21
22
23
24
25
# File 'lib/einvoicing/connect/fr/pennylane/client.rb', line 21

def initialize(credentials:, sandbox: false)
  @credentials = credentials
  @base_url    = sandbox ? SANDBOX_URL : BASE_URL
  @oauth_base  = sandbox ? OAUTH_SANDBOX_URL : OAUTH_BASE_URL
end

Instance Method Details

#create_company_customer(attributes) ⇒ Object

Create a company customer (an organisation, invoiced under its own name).

Parameters:

  • attributes (Hash)

    at least name and billing_address; reg_no carries the SIRET, external_reference the caller's key.



58
59
60
# File 'lib/einvoicing/connect/fr/pennylane/client.rb', line 58

def create_company_customer(attributes)
  post("/company_customers", attributes)
end

#create_individual_customer(attributes) ⇒ Object

Create an individual customer (a private person).



63
64
65
# File 'lib/einvoicing/connect/fr/pennylane/client.rb', line 63

def create_individual_customer(attributes)
  post("/individual_customers", attributes)
end

#customer_by_reference(reference) ⇒ Hash?

Find a customer by the caller's own identifier.

Pennylane does not match a customer from the invoice itself: a document imported without customer_id lands as "incomplete" with customer nil, whatever SIRET or VAT number the Factur-X carries. external_reference is the caller's key into Pennylane's own numbering, which is what makes resolution repeatable.

Returns:

  • (Hash, nil)

    the customer, or nil when none carries that reference



49
50
51
52
# File 'lib/einvoicing/connect/fr/pennylane/client.rb', line 49

def customer_by_reference(reference)
  filter = JSON.generate([ { field: "external_reference", operator: "eq", value: reference } ])
  get("/customers?filter=#{CGI.escape(filter)}")["items"]&.first
end

#find_or_create_customer(reference:, attributes:, company: true) ⇒ Object

The customer for reference, created from attributes if Pennylane does not know it yet. Idempotent as long as the caller keeps the reference stable, which is the point of it.

Parameters:

  • company (Boolean) (defaults to: true)

    an organisation rather than a private person



72
73
74
75
76
77
78
# File 'lib/einvoicing/connect/fr/pennylane/client.rb', line 72

def find_or_create_customer(reference:, attributes:, company: true)
  existing = customer_by_reference(reference)
  return existing if existing

  payload = attributes.merge(external_reference: reference)
  company ? create_company_customer(payload) : create_individual_customer(payload)
end

#invoice_status(id) ⇒ Object

Get invoice status by Pennylane invoice ID.



36
37
38
# File 'lib/einvoicing/connect/fr/pennylane/client.rb', line 36

def invoice_status(id)
  get("/customer_invoices/#{id}")
end

#submit_einvoice(facturx_pdf, filename: "factur-x.pdf", invoice_options: nil) ⇒ Object

Submit a Factur-X PDF binary to the e-invoice import endpoint. invoice_options: optional Hash pre-filling customer/line data.



29
30
31
32
33
# File 'lib/einvoicing/connect/fr/pennylane/client.rb', line 29

def submit_einvoice(facturx_pdf, filename: "factur-x.pdf", invoice_options: nil)
  post_multipart("/customer_invoices/e_invoices/imports",
                 file: facturx_pdf, filename: filename,
                 invoice_options: invoice_options)
end