Class: Ksef::FA3::Subject

Inherits:
Data
  • Object
show all
Includes:
Canonical
Defined in:
lib/ksef/fa3/subject.rb,
lib/ksef/fa3/subject.rb

Overview

Roles, defaults and serialisation for Subject. Reopened rather than using a Data.define block so the constants land on the class.

Constant Summary collapse

ELEMENTS =

The element each role writes into. Also the role whitelist: a role not named here is refused rather than silently treated as a buyer.

{
  seller: "Podmiot1", buyer: "Podmiot2",
  previous_seller: "Podmiot1K", previous_buyer: "Podmiot2K"
}.freeze
NAMED_PARTIES =

Podmiot1 and Podmiot1K both make Nazwa and Adres mandatory; the two buyer roles make both optional.

%i[seller previous_seller].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Canonical

#with

Constructor Details

#initialize(nip:, address: nil, name: nil, local_government_unit: false, vat_group_member: false, buyer_id: nil) ⇒ Subject

Every field is canonicalised to what the document will carry (§8.2b). The two flags in particular: Ksef::FA3::SubjectReader reads them back through Formatting.unflag as booleans, so a caller passing "1" — which tier 1 used to bless — built an invoice that could never equal its own parsed form.



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ksef/fa3/subject.rb', line 51

def initialize(nip:, address: nil, name: nil, local_government_unit: false,
               vat_group_member: false, buyer_id: nil)
  super(
    address: address,
    nip: self.class.normalized_nip(nip),
    name: Formatting.text(name),
    buyer_id: Formatting.text(buyer_id),
    local_government_unit: Formatting.unflag(local_government_unit),
    vat_group_member: Formatting.unflag(vat_group_member)
  )
end

Instance Attribute Details

#address ⇒ Object (readonly)

Returns the value of attribute address

Returns:

  • (Object) —

    the current value of address



29
30
31
# File 'lib/ksef/fa3/subject.rb', line 29

def address
  @address
end

#buyer_id ⇒ Object (readonly)

Returns the value of attribute buyer_id

Returns:

  • (Object) —

    the current value of buyer_id



29
30
31
# File 'lib/ksef/fa3/subject.rb', line 29

def buyer_id
  @buyer_id
end

#local_government_unit ⇒ Object (readonly)

Returns the value of attribute local_government_unit

Returns:

  • (Object) —

    the current value of local_government_unit



29
30
31
# File 'lib/ksef/fa3/subject.rb', line 29

def local_government_unit
  @local_government_unit
end

#name ⇒ Object (readonly)

Returns the value of attribute name

Returns:

  • (Object) —

    the current value of name



29
30
31
# File 'lib/ksef/fa3/subject.rb', line 29

def name
  @name
end

#nip ⇒ Object (readonly)

Returns the value of attribute nip

Returns:

  • (Object) —

    the current value of nip



29
30
31
# File 'lib/ksef/fa3/subject.rb', line 29

def nip
  @nip
end

#vat_group_member ⇒ Object (readonly)

Returns the value of attribute vat_group_member

Returns:

  • (Object) —

    the current value of vat_group_member



29
30
31
# File 'lib/ksef/fa3/subject.rb', line 29

def vat_group_member
  @vat_group_member
end

Class Method Details

.normalized_nip(value) ⇒ Object

NIP.normalize accepts the written forms an ERP sends — "123-456-32-18", "PL…" — so canonicalising here is what makes those equal to the ten digits a document carries. Text tagged UTF-8 that is not passes through untouched, for the reason Formatting.text explains: strip raises on it, and tier 1 is what reports it.



67
68
69
70
71
# File 'lib/ksef/fa3/subject.rb', line 67

def self.normalized_nip(value)
  return value if value.nil? || !value.to_s.valid_encoding?

  NIP.normalize(value)
end

Instance Method Details

#to_fa3(role:) ⇒ Object

Parameters:

  • role (Symbol) —

    :seller, :buyer, :previous_seller or :previous_buyer

Raises:

  • (Ksef::ValidationError) —

    if a seller is missing a name or an address, or the role is not one of the four



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ksef/fa3/subject.rb', line 76

def to_fa3(role:)
  element = element_for(role)
  content = { "DaneIdentyfikacyjne" => identity_for(role, element) }
  if address.nil?
    raise ValidationError, "A #{role} (#{element}) must have an address" if NAMED_PARTIES.include?(role)
  else
    content["Adres"] = address.to_fa3
  end

  content.merge(buyer_fields(role)).compact
end