diff --git a/lib/xeroizer.rb b/lib/xeroizer.rb index a328b00a..a8dcdeb7 100644 --- a/lib/xeroizer.rb +++ b/lib/xeroizer.rb @@ -43,7 +43,8 @@ ['home_address', 'bank_account', 'employee', 'timesheet', 'timesheet_line', 'number_of_unit', 'leave_application', 'leave_period', 'pay_items', 'deduction_type', 'earnings_rate', 'reimbursement_type', 'leave_type', 'payroll_calendar', 'pay_template', 'super_membership', - 'leave_line', 'reimbursement_line', 'super_line', 'deduction_line', 'earnings_line', 'opening_balance'].each do |payroll_model| + 'leave_line', 'reimbursement_line', 'super_line', 'deduction_line', 'earnings_line', 'opening_balance', + 'pay_run', 'settings', 'tracking_categories', 'employee_groups', 'timesheet_categories', 'account'].each do |payroll_model| require "xeroizer/models/payroll/#{payroll_model}" end diff --git a/lib/xeroizer/generic_application.rb b/lib/xeroizer/generic_application.rb index 2a2e7d53..bd7921e8 100644 --- a/lib/xeroizer/generic_application.rb +++ b/lib/xeroizer/generic_application.rb @@ -46,7 +46,7 @@ class GenericApplication # @see PrivateApplication # @see PartnerApplication def initialize(consumer_key, consumer_secret, options = {}) - @xero_url_prefix = options[:xero_url_prefix] || "https://api.xero.com/" + @xero_url_prefix = options[:xero_url_prefix] || "https://api.xero.com" @xero_url_suffix = options[:xero_url_suffix] || "api.xro/2.0" @rate_limit_sleep = options[:rate_limit_sleep] || false @rate_limit_max_attempts = options[:rate_limit_max_attempts] || 5 diff --git a/lib/xeroizer/models/payroll/account.rb b/lib/xeroizer/models/payroll/account.rb new file mode 100644 index 00000000..d377fc95 --- /dev/null +++ b/lib/xeroizer/models/payroll/account.rb @@ -0,0 +1,21 @@ +module Xeroizer + module Record + module Payroll + + class AccountModel < PayrollBaseModel + + set_permissions :read + + end + + class Account < PayrollBase + + string :type + string :code + string :name + guid :account_id + end + + end + end +end diff --git a/lib/xeroizer/models/payroll/employee_groups.rb b/lib/xeroizer/models/payroll/employee_groups.rb new file mode 100644 index 00000000..a4b5397f --- /dev/null +++ b/lib/xeroizer/models/payroll/employee_groups.rb @@ -0,0 +1,24 @@ +module Xeroizer + module Record + module Payroll + + class EmployeeGroupsModel < PayrollBaseModel + + set_standalone_model true + set_xml_root_name 'EmployeeGroups' + set_xml_node_name 'EmployeeGroups' + end + + # child of TrackingCategories + class EmployeeGroups < PayrollBase + + set_primary_key false + + guid :tracking_category_id + string :tracking_category_name + + end + + end + end +end diff --git a/lib/xeroizer/models/payroll/leave_application.rb b/lib/xeroizer/models/payroll/leave_application.rb index 060b4500..de1b0b34 100644 --- a/lib/xeroizer/models/payroll/leave_application.rb +++ b/lib/xeroizer/models/payroll/leave_application.rb @@ -5,8 +5,6 @@ module Payroll class LeaveApplicationModel < PayrollBaseModel set_permissions :read, :write, :update - - # TODO: calling #get on this requries an employee ID end class LeaveApplication < PayrollBase diff --git a/lib/xeroizer/models/payroll/opening_balance.rb b/lib/xeroizer/models/payroll/opening_balance.rb index f0691083..90fb7fb2 100644 --- a/lib/xeroizer/models/payroll/opening_balance.rb +++ b/lib/xeroizer/models/payroll/opening_balance.rb @@ -4,7 +4,7 @@ module Payroll class OpeningBalancesModel < PayrollBaseModel - set_all_children_are_subtypes true + set_standalone_model true set_xml_root_name 'OpeningBalances' set_xml_node_name 'OpeningBalances' end diff --git a/lib/xeroizer/models/payroll/pay_items.rb b/lib/xeroizer/models/payroll/pay_items.rb index 12ed7345..d1a27296 100644 --- a/lib/xeroizer/models/payroll/pay_items.rb +++ b/lib/xeroizer/models/payroll/pay_items.rb @@ -6,7 +6,7 @@ class PayItemModel < PayrollBaseModel set_permissions :read, :write, :update - set_all_children_are_subtypes true + set_standalone_model true set_xml_root_name 'PayItems' set_xml_node_name 'PayItems' end diff --git a/lib/xeroizer/models/payroll/pay_run.rb b/lib/xeroizer/models/payroll/pay_run.rb new file mode 100644 index 00000000..2953346c --- /dev/null +++ b/lib/xeroizer/models/payroll/pay_run.rb @@ -0,0 +1,40 @@ +module Xeroizer + module Record + module Payroll + + class PayRunModel < PayrollBaseModel + + set_permissions :read, :write, :update + + end + + # http://developer.xero.com/documentation/payroll-api/payruns/ + class PayRun < PayrollBase + + set_primary_key :pay_run_id + + guid :pay_run_id + + guid :payroll_calendar_id + + date :pay_run_period_end_date + date :pay_run_period_start_date + date :payment_date + + decimal :wages + decimal :deductions + decimal :tax + decimal :super + decimal :reimbursement + decimal :net_pay + + string :pay_run_status + string :payslip_message + + #has_many :payslips + + end + + end + end +end diff --git a/lib/xeroizer/models/payroll/pay_template.rb b/lib/xeroizer/models/payroll/pay_template.rb index 02fcb097..ce70dc2d 100644 --- a/lib/xeroizer/models/payroll/pay_template.rb +++ b/lib/xeroizer/models/payroll/pay_template.rb @@ -4,7 +4,7 @@ module Payroll class PayTemplateModel < PayrollBaseModel - set_all_children_are_subtypes true + set_standalone_model true set_xml_root_name 'PayTemplate' set_xml_node_name 'PayTemplate' end diff --git a/lib/xeroizer/models/payroll/payslip.rb b/lib/xeroizer/models/payroll/payslip.rb new file mode 100644 index 00000000..155c864e --- /dev/null +++ b/lib/xeroizer/models/payroll/payslip.rb @@ -0,0 +1,31 @@ +module Xeroizer + module Record + module Payroll + + class PayslipModel < PayrollBaseModel + + set_permissions :read, :update + + end + + # http://developer.xero.com/documentation/payroll-api/payslip/ + class Payslip < PayrollBase + + set_primary_key :payslip_id + + guid :payslip_id + + guid :employee_id + + has_many :earnings_lines + #has_many :timesheet_earnings_lines # TODO + has_many :deduction_lines + #has_many :leave_accrual_lines # TODO + has_many :superannuation_lines, :internal_name_singular => "super_line", :model_name => "SuperLine" + has_many :reimbursement_lines + + end + + end + end +end diff --git a/lib/xeroizer/models/payroll/settings.rb b/lib/xeroizer/models/payroll/settings.rb new file mode 100644 index 00000000..568d51cf --- /dev/null +++ b/lib/xeroizer/models/payroll/settings.rb @@ -0,0 +1,27 @@ +module Xeroizer + module Record + module Payroll + + class SettingModel < PayrollBaseModel + + set_permissions :read + + set_standalone_model true + set_xml_root_name 'Settings' + set_xml_node_name 'Settings' + end + + class Setting < PayrollBase + + set_primary_key false + + has_many :accounts + has_many :timesheet_categories, :model_name => 'TimesheetCategories' + has_many :employee_groups, :model_name => 'EmployeeGroups' + integer :days_in_payroll_year + + end + + end + end +end diff --git a/lib/xeroizer/models/payroll/super_line.rb b/lib/xeroizer/models/payroll/super_line.rb index 31035c41..2500de52 100644 --- a/lib/xeroizer/models/payroll/super_line.rb +++ b/lib/xeroizer/models/payroll/super_line.rb @@ -15,8 +15,11 @@ class SuperLine < PayrollBase string :expense_account_code string :liability_account_code + date :payment_date_for_this_period + decimal :minimum_monthly_earnings decimal :percentage + decimal :amount end diff --git a/lib/xeroizer/models/payroll/timesheet_categories.rb b/lib/xeroizer/models/payroll/timesheet_categories.rb new file mode 100644 index 00000000..fb1572ba --- /dev/null +++ b/lib/xeroizer/models/payroll/timesheet_categories.rb @@ -0,0 +1,24 @@ +module Xeroizer + module Record + module Payroll + + class TimesheetCategoriesModel < PayrollBaseModel + + set_standalone_model true + set_xml_root_name 'TimesheetCategories' + set_xml_node_name 'TimesheetCategories' + end + + # child of TrackingCategories + class TimesheetCategories < PayrollBase + + set_primary_key false + + guid :tracking_category_id + string :tracking_category_name + + end + + end + end +end diff --git a/lib/xeroizer/models/payroll/tracking_categories.rb b/lib/xeroizer/models/payroll/tracking_categories.rb new file mode 100644 index 00000000..ff3a632a --- /dev/null +++ b/lib/xeroizer/models/payroll/tracking_categories.rb @@ -0,0 +1,26 @@ +module Xeroizer + module Record + module Payroll + + class TrackingCategoriesModel < PayrollBaseModel + + set_permissions :read + + set_standalone_model true + set_xml_root_name 'TrackingCategories' + set_xml_node_name 'TrackingCategories' + end + + # child of Settings + class TrackingCategories < PayrollBase + + set_primary_key false + + has_many :employee_groups + has_many :timesheet_categories + + end + + end + end +end diff --git a/lib/xeroizer/payroll_application.rb b/lib/xeroizer/payroll_application.rb index 4e63acd6..08cde9e6 100644 --- a/lib/xeroizer/payroll_application.rb +++ b/lib/xeroizer/payroll_application.rb @@ -29,6 +29,9 @@ def self.record(record_type) record :PayItem record :PayrollCalendar record :LeaveApplication + record :PayRun + record :Payslip + record :Setting def initialize(application) @application = application diff --git a/lib/xeroizer/record/base_model.rb b/lib/xeroizer/record/base_model.rb index 10b9d732..8fa077b0 100644 --- a/lib/xeroizer/record/base_model.rb +++ b/lib/xeroizer/record/base_model.rb @@ -18,7 +18,7 @@ class InvalidPermissionError < StandardError class_inheritable_attributes :xml_root_name class_inheritable_attributes :optional_xml_root_name class_inheritable_attributes :xml_node_name - class_inheritable_attributes :all_children_are_subtypes + class_inheritable_attributes :standalone_model include BaseModelHttpProxy @@ -71,8 +71,8 @@ def set_optional_xml_root_name(optional_root_name) # If this is true, the tag isn't expected. So it would be # # Example: http://developer.xero.com/payroll-api/PayItems/#GET - def set_all_children_are_subtypes(boolean) - self.all_children_are_subtypes = boolean + def set_standalone_model(boolean) + self.standalone_model = boolean end end @@ -180,7 +180,7 @@ def parse_response(response_xml, options = {}) if model_name == response_model_name @response = response parse_records(response, elements, (options[:base_module] || Xeroizer::Record)) - elsif self.class.all_children_are_subtypes && self.class.xml_root_name == elements.first.parent.name + elsif self.class.standalone_model && self.class.xml_root_name == elements.first.parent.name @response = response parse_records(response, elements, (options[:base_module] || Xeroizer::Record), true) end @@ -190,21 +190,31 @@ def parse_response(response_xml, options = {}) protected # Parse the records part of the XML response and builds model instances as necessary. - def parse_records(response, elements, base_module, all_children_are_subtypes = false) + def parse_records(response, elements, base_module, standalone_model = false) elements.each do | element | - new_record = model_class.build_from_node(element, self, base_module, all_children_are_subtypes) + new_record = model_class.build_from_node(element, self, base_module, standalone_model) if element.attribute('status').try(:value) == 'ERROR' new_record.errors = [] element.xpath('.//ValidationError').each do |err| new_record.errors << err.text.gsub(/^\s+/, '').gsub(/\s+$/, '') end end - if all_children_are_subtypes + if standalone_model if response.response_items.count == 0 response.response_items << new_record else - field_to_fill = model_class.fields.find {|f| new_record[f[0]].count > 0} - (response.response_items.first[field_to_fill[0]] = new_record[field_to_fill[0]]) unless field_to_fill.nil? + # http://developer.xero.com/documentation/payroll-api/settings/ + # tracking categories have subcategories of timesheet categoires and employee groups + # which we group together here as it's much easier to model + fields_to_fill = model_class.fields.find_all do |f| + new_record_field = new_record[f[0]] + if new_record_field.respond_to?(:count) + new_record_field.count > 0 + else + !new_record_field.nil? + end + end + fields_to_fill.each {|field| response.response_items.first[field[0]] = new_record[field[0]]} end else response.response_items << new_record diff --git a/lib/xeroizer/record/record_association_helper.rb b/lib/xeroizer/record/record_association_helper.rb index 8f822155..5a2b9c12 100644 --- a/lib/xeroizer/record/record_association_helper.rb +++ b/lib/xeroizer/record/record_association_helper.rb @@ -16,6 +16,7 @@ def belongs_to(field_name, options = {}) # Create a #build_record_name method to build the record. define_method "build_#{internal_singular_field_name}" do | *args | + attributes = args.size == 1 ? args.first : {} # The name of the record model. diff --git a/lib/xeroizer/record/xml_helper.rb b/lib/xeroizer/record/xml_helper.rb index 2d0246d2..465c4eba 100644 --- a/lib/xeroizer/record/xml_helper.rb +++ b/lib/xeroizer/record/xml_helper.rb @@ -12,10 +12,10 @@ def self.included(base) module ClassMethods # Build a record instance from the XML node. - def build_from_node(node, parent, base_module, all_children_are_subtypes = false) + def build_from_node(node, parent, base_module, standalone_model = false) record = new(parent) node.elements.each do | element | - element_name = all_children_are_subtypes ? element.name.to_s.pluralize : element.name.to_s + element_name = standalone_model ? element.name.to_s.pluralize : element.name.to_s field = self.fields[element_name.underscore.to_sym] if field value = case field[:type] @@ -33,9 +33,9 @@ def build_from_node(node, parent, base_module, all_children_are_subtypes = false when :has_many if element.element_children.size > 0 - sub_field_name = field[:model_name] ? field[:model_name].to_sym : (all_children_are_subtypes ? element.name : element.children.first.name).to_sym + sub_field_name = field[:model_name] ? field[:model_name].to_sym : (standalone_model ? element.name : element.children.first.name).to_sym sub_parent = record.new_model_class(sub_field_name) - if all_children_are_subtypes + if standalone_model base_module.const_get(sub_field_name).build_from_node(element, sub_parent, base_module) else element.children.inject([]) do | list, element | @@ -56,7 +56,7 @@ def build_from_node(node, parent, base_module, all_children_are_subtypes = false end if field[:calculated] record.attributes[field[:internal_name]] = value - elsif all_children_are_subtypes + elsif standalone_model record.send("add_#{field[:internal_name].to_s.singularize}".to_sym, value) else record.send("#{field[:internal_name]}=".to_sym, value) diff --git a/privatekey.pem b/privatekey.pem new file mode 100644 index 00000000..e11a8af1 --- /dev/null +++ b/privatekey.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDsJmYfpxau21Z1/7khZsiB6ZKX/BeurXUtX4LAEUNDjZe7Ytv1 +Vi+iWTkig+QXDO0YRiKqX6rLpQWlJDjIt6rzjSa8FEr6KBC+U2PBEv98FjQ8ZfvL +ty9vCewIrjk0iCifzgv/K14pA+aoJRE8IRmnoVVkDiGNj2Ds/YGkImgjYQIDAQAB +AoGALDsI97bBDeExMYrDLxlkRsjr1yG1gdclUmlIQRc6pQV5PPTIRAxvgZX6mJdh +elvGcLx6M7UVdW0kQIknRZj5IKbR9HP8SbuUtaKeofDAK2UFtVbnYB9qkWeYR0+q +IjDI1l+m7gK+AEg6/WVHC6woE94GTgSK1tBgN7HjjjEZkA0CQQD9qzvWf/9Sy2zP +KLq/5iEVMNHX5PmiqMqA7sPTtaQ4ij55snnlDHMKf8QxHXSMDlhmkU7vimQiKnto +UEh6KALfAkEA7lHziAB1fIWXGqerbcVTeJ3tI4YlbDVfesBvi7aEN3JZ5Q8YP9/n +BXNeqRfRnAPdFfkzR5MGZ+osjJhcdPjhvwJAI2KdiEB2p2AFH6i41EgP2VrkCs/A +GvacuPuViZTPAawXJvbEljT0X0SPY6KOPXNK1ZPzhOqzKSjv6g847QFj1QJAcRtz ++Zg+Kls82+m38uE0PIq3gaSpHjI2nou2ZRi6p5YeFBiV6braajvXMWmcke9DfqpH +LDEbWTZK7m9hciKtAQJBALBcn/xLbuP7xnn8SVdqEfxgK8L2rVJvrSl+yepohLHG +QGOpLqvJUjG4mU8Go5YPwrkyDdKpqsbxKB7ax1OGLoc= +-----END RSA PRIVATE KEY----- diff --git a/public_privatekey.pfx b/public_privatekey.pfx new file mode 100644 index 00000000..0b2a6168 Binary files /dev/null and b/public_privatekey.pfx differ diff --git a/publickey.cer b/publickey.cer new file mode 100644 index 00000000..1b9c1fea --- /dev/null +++ b/publickey.cer @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDYDCCAsmgAwIBAgIJAMWGDPGFjZcwMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZOdW5kYWgxDzAN +BgNVBAoTBlBheUF1czEYMBYGA1UEAxMPQWxleCBHaGljdWxlc2N1MR4wHAYJKoZI +hvcNAQkBFg9hbGV4QHBheWF1cy5jb20wHhcNMTMwNTMwMDUyMjE0WhcNMTQwNTMw +MDUyMjE0WjB+MQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEPMA0G +A1UEBxMGTnVuZGFoMQ8wDQYDVQQKEwZQYXlBdXMxGDAWBgNVBAMTD0FsZXggR2hp +Y3VsZXNjdTEeMBwGCSqGSIb3DQEJARYPYWxleEBwYXlhdXMuY29tMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQDsJmYfpxau21Z1/7khZsiB6ZKX/BeurXUtX4LA +EUNDjZe7Ytv1Vi+iWTkig+QXDO0YRiKqX6rLpQWlJDjIt6rzjSa8FEr6KBC+U2PB +Ev98FjQ8ZfvLty9vCewIrjk0iCifzgv/K14pA+aoJRE8IRmnoVVkDiGNj2Ds/YGk +ImgjYQIDAQABo4HlMIHiMB0GA1UdDgQWBBTAfUPCLmW+/3WCAHmN3yZWeDDypjCB +sgYDVR0jBIGqMIGngBTAfUPCLmW+/3WCAHmN3yZWeDDypqGBg6SBgDB+MQswCQYD +VQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEPMA0GA1UEBxMGTnVuZGFoMQ8w +DQYDVQQKEwZQYXlBdXMxGDAWBgNVBAMTD0FsZXggR2hpY3VsZXNjdTEeMBwGCSqG +SIb3DQEJARYPYWxleEBwYXlhdXMuY29tggkAxYYM8YWNlzAwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQUFAAOBgQDcecLBQTiyfrtqZHXNdpJj0BzAvyFO4D9PuenM +CYTe/hYncSaapngNrFUuakUpN/zVag/PoV0Ag0HNBsyexq12gCkbdhhtAYD/hXYV +4/i2Tgy1H5ct6kBv2u/e5GtSGrVKiIHWcTF5tPGlXg75w49yi9iyxBNDjNFFyYpM +hCpGmg== +-----END CERTIFICATE----- diff --git a/test/dummy_script.rb b/test/dummy_script.rb new file mode 100644 index 00000000..fe341a51 --- /dev/null +++ b/test/dummy_script.rb @@ -0,0 +1,26 @@ +require "pp" +require "logger" +require 'rubygems' +require 'debugger' +require 'net-http-spy' + +Net::HTTP.http_logger_options = {verbose: true, body: true, trace: true} + +require File.dirname(__FILE__) + "/../lib/xeroizer" + +xero = Xeroizer::PrivateApplication.new( + 'JRKZQGSECLTD6PZBLVRDKZGGELNRI1', + 'QXJLLZK63AM29DO0GPRIR3ABPNZYRM', + File.dirname(__FILE__) + "/../privatekey.pem" + ).payroll + +#xero = Xeroizer::PublicApplication.new( +# 'JRKZQGSECLTD6PZBLVRDKZGGELNRI1', +# 'QXJLLZK63AM29DO0GPRIR3ABPNZYRM' +# ).payroll +#url = xero.request_token(:oauth_callback => 'http://developer.xero.com/payroll-api/') + +xero.logger = Logger.new(STDOUT) + +puts xero.Employee.url +puts xero.Timesheet.url \ No newline at end of file diff --git a/test/stub_responses/payroll_leave_applications.xml b/test/stub_responses/payroll_leave_applications.xml index 77dbef09..88dda278 100644 --- a/test/stub_responses/payroll_leave_applications.xml +++ b/test/stub_responses/payroll_leave_applications.xml @@ -5,10 +5,10 @@ 2013-05-30T05:25:03.0599507Z - 07c60af4-5c86-44d9-8146-fab3733a087c + fb4ebd68-6568-41eb-96ab-628a0f54b4b8 ACTIVE - Alex - Ghiculescu + LeBron + James 2013-04-18T01:29:53 diff --git a/test/stub_responses/payroll_pay_runs.xml b/test/stub_responses/payroll_pay_runs.xml new file mode 100644 index 00000000..b26cd55d --- /dev/null +++ b/test/stub_responses/payroll_pay_runs.xml @@ -0,0 +1,34 @@ + + a1b8088e-4166-48e9-9e29-5b5919cac0a0 + OK + Xeroizer test + 2013-05-30T05:25:03.0599507Z + + + 260.04 + 18831.25 + e3bdb2f7-2b20-45e6-ac8d-ec67d17de9f4 + 2012-01-07T00:00:00 + 2012-01-01T00:00:00 + Posted + 2012-01-08T00:00:00 + bfac31bd-ea62-4fc8-a5e7-7965d9504b15 + 2539.97 + 6651.00 + 25742.29 + + + 260.04 + 22463.25 + 7c998e04-1cee-4a19-bfe6-3cbfd5cb9cea + 2012-01-14T00:00:00 + 2012-01-08T00:00:00 + Posted + 2012-01-15T00:00:00 + bfac31bd-ea62-4fc8-a5e7-7965d9504b15 + 2892.78 + 6939.00 + 29662.29 + + + \ No newline at end of file diff --git a/test/stub_responses/records/payroll_employee-07c60af4-5c86-44d9-8146-fab3733a087c.xml b/test/stub_responses/records/payroll_employee-07c60af4-5c86-44d9-8146-fab3733a087c.xml deleted file mode 100644 index 31a929c1..00000000 --- a/test/stub_responses/records/payroll_employee-07c60af4-5c86-44d9-8146-fab3733a087c.xml +++ /dev/null @@ -1,147 +0,0 @@ - - 07c60af4-5c86-44d9-8146-fab3733a087d - OK - Demo AU - 2011-05-31T01:18:05.1105867Z - - - 07c60af4-5c86-44d9-8146-fab3733a087c - James - Lebron - ACTIVE - JL@madeup.email.com - 1978-08-13T00:00:00 - M - - 123 Main St - St. Kilda - VIC - 3182 - AUSTRALIA - - 0400-000-123 - 408-230-9732 - 2012-01-30T00:00:00 - 72e962d1-fcac-4083-8a71-742bb3e7ae14 - cb8e4706-2fdc-4170-aebd-0ffb855557f5 - 2013-04-01T23:02:36 - false - - false - true - true - false - false - false - 2013-04-26T00:04:48 - - - - Salary - James Lebron Savings - 122344 - 345678 - false - 20.0000 - - - Salary - James Lebron - 123443 - 2345678 - true - - - - 2012-07-01T00:00:00 - - - 72e962d1-fcac-4083-8a71-742bb3e7ae14 - 13333.33 - - - - - 59cd9d04-4521-4cc3-93ac-7841651ff407 - 40.00 - - - 4000.00 - - - 4333d5cd-53a5-4c31-98e5-a8b4e5676b0b - SGC - 3999.99 - - - - - - 742998cb-7584-4ecf-aa88-d694f59c50f9 - 100.0000 - - - 3bc7b584-a49f-40c6-ac5e-891f382785c9 - 40.0000 - - - - - - - 72e962d1-fcac-4083-8a71-742bb3e7ae14 - ANNUALSALARY - 40000.00 - 38.0000 - - - - - 59cd9d04-4521-4cc3-93ac-7841651ff407 - FIXEDAMOUNT - 10.00 - - - - - 4333d5cd-53a5-4c31-98e5-a8b4e5676b0b - SGC - PERCENTAGEOFEARNINGS - 450.00 - 478 - 826 - 9.0000 - - - 4333d5cd-53a5-4c31-98e5-a8b4e5676b0b - SALARYSACRIFICE - FIXEDAMOUNT - 478 - 826 - 50.0000 - - - - - - 742998cb-7584-4ecf-aa88-d694f59c50f9 - FIXEDAMOUNTEACHPERIOD - 152.0000 - - - 3bc7b584-a49f-40c6-ac5e-891f382785c9 - FIXEDAMOUNTEACHPERIOD - 76.0000 - - - - - - 4333d5cd-53a5-4c31-98e5-a8b4e5676b0b - 2187a42b-639a-45cb-9eed-cd4ae488306a - 1234 - - - - - \ No newline at end of file diff --git a/test/stub_responses/records/payroll_employee-fb4ebd68-6568-41eb-96ab-628a0f54b4b8.xml b/test/stub_responses/records/payroll_employee-fb4ebd68-6568-41eb-96ab-628a0f54b4b8.xml index 08fa1ede..0ebd36ac 100644 --- a/test/stub_responses/records/payroll_employee-fb4ebd68-6568-41eb-96ab-628a0f54b4b8.xml +++ b/test/stub_responses/records/payroll_employee-fb4ebd68-6568-41eb-96ab-628a0f54b4b8.xml @@ -5,7 +5,7 @@ 2011-05-31T01:18:05.1105867Z - 07c60af4-5c86-44d9-8146-fab3733a087c + fb4ebd68-6568-41eb-96ab-628a0f54b4b8 James Lebron ACTIVE diff --git a/test/stub_responses/records/payroll_leave_application-07c60af4-5c86-44d9-8146-fab3733a087c.xml b/test/stub_responses/records/payroll_leave_application-fb4ebd68-6568-41eb-96ab-628a0f54b4b8.xml similarity index 94% rename from test/stub_responses/records/payroll_leave_application-07c60af4-5c86-44d9-8146-fab3733a087c.xml rename to test/stub_responses/records/payroll_leave_application-fb4ebd68-6568-41eb-96ab-628a0f54b4b8.xml index e2ca22e2..770adc67 100644 --- a/test/stub_responses/records/payroll_leave_application-07c60af4-5c86-44d9-8146-fab3733a087c.xml +++ b/test/stub_responses/records/payroll_leave_application-fb4ebd68-6568-41eb-96ab-628a0f54b4b8.xml @@ -6,7 +6,7 @@ e0eb6747-7c17-4075-b804-989f8d4e5d39 - 07c60af4-5c86-44d9-8146-fab3733a087c + fb4ebd68-6568-41eb-96ab-628a0f54b4b8 742998cb-7584-4ecf-aa88-d694f59c50f9 diff --git a/test/stub_responses/records/payroll_payroll_run-7c998e04-1cee-4a19-bfe6-3cbfd5cb9cea.xml b/test/stub_responses/records/payroll_payroll_run-7c998e04-1cee-4a19-bfe6-3cbfd5cb9cea.xml new file mode 100644 index 00000000..50d463e8 --- /dev/null +++ b/test/stub_responses/records/payroll_payroll_run-7c998e04-1cee-4a19-bfe6-3cbfd5cb9cea.xml @@ -0,0 +1,62 @@ + + 49713875-ad73-492c-b6ac-2d265a5fe862 + OK + Demo AU + 2011-05-31T01:18:05.1105867Z + + + 260.04 + 18831.25 + 7c998e04-1cee-4a19-bfe6-3cbfd5cb9cea + 2012-01-07T00:00:00 + 2012-01-01T00:00:00 + Posted + 2012-01-08T00:00:00 + bfac31bd-ea62-4fc8-a5e7-7965d9504b15 + + + 0.00 + f3f29c96-77d7-44f0-80fc-0e87dea2320d + Bucky + 2012-03-27T23:33:35 + Lasek + 441.00 + 2d3a0cf2-6b1c-499d-a2bb-dda0cdad7634 + 0.00 + 43.56 + 43.00 + 484.00 + + + 0.00 + dcdb554d-2dbf-4a4f-99dd-c3fc6fafb7f3 + Chet + 2012-03-27T23:33:39 + Taylor + 1261.20 + 3586f5b4-9a04-4c2d-8ab6-3e1b34de0b62 + 0.00 + 151.31 + 420.00 + 1681.20 + + + 0.00 + c3896c4a-da46-489c-89c6-e48bcef655ef + Ray + 2012-03-27T23:41:28 + Barbee + 889.33 + c7196baa-3248-4801-ad7b-ae353b7b2f8c + 0.00 + 100.11 + 223.00 + 1112.33 + + + 2539.97 + 6651.00 + 25742.29 + + + \ No newline at end of file diff --git a/test/stub_responses/records/payroll_payroll_run-e3bdb2f7-2b20-45e6-ac8d-ec67d17de9f4.xml b/test/stub_responses/records/payroll_payroll_run-e3bdb2f7-2b20-45e6-ac8d-ec67d17de9f4.xml new file mode 100644 index 00000000..47b7ca55 --- /dev/null +++ b/test/stub_responses/records/payroll_payroll_run-e3bdb2f7-2b20-45e6-ac8d-ec67d17de9f4.xml @@ -0,0 +1,62 @@ + + 49713875-ad73-492c-b6ac-2d265a5fe862 + OK + Demo AU + 2011-05-31T01:18:05.1105867Z + + + 260.04 + 18831.25 + e3bdb2f7-2b20-45e6-ac8d-ec67d17de9f4 + 2012-01-07T00:00:00 + 2012-01-01T00:00:00 + Posted + 2012-01-08T00:00:00 + bfac31bd-ea62-4fc8-a5e7-7965d9504b15 + + + 0.00 + f3f29c96-77d7-44f0-80fc-0e87dea2320d + Bucky + 2012-03-27T23:33:35 + Lasek + 441.00 + 2d3a0cf2-6b1c-499d-a2bb-dda0cdad7634 + 0.00 + 43.56 + 43.00 + 484.00 + + + 0.00 + dcdb554d-2dbf-4a4f-99dd-c3fc6fafb7f3 + Chet + 2012-03-27T23:33:39 + Taylor + 1261.20 + 3586f5b4-9a04-4c2d-8ab6-3e1b34de0b62 + 0.00 + 151.31 + 420.00 + 1681.20 + + + 0.00 + c3896c4a-da46-489c-89c6-e48bcef655ef + Ray + 2012-03-27T23:41:28 + Barbee + 889.33 + c7196baa-3248-4801-ad7b-ae353b7b2f8c + 0.00 + 100.11 + 223.00 + 1112.33 + + + 2539.97 + 6651.00 + 25742.29 + + + \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index 4d3d63bf..42f52522 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -30,7 +30,12 @@ module TestHelper GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ unless defined?(GUID_REGEX) def get_file_as_string(filename) - File.read(File.dirname(__FILE__) + "/stub_responses/" + filename) + if File.exist?(File.dirname(__FILE__) + "/stub_responses/" + filename) + File.read(File.dirname(__FILE__) + "/stub_responses/" + filename) + else + puts "WARNING: File does not exist: #{filename}" + nil + end end def get_record_xml(type, id = nil) @@ -52,6 +57,22 @@ def mock_api(model_name) client_for_stubbing.stubs(:http_get).with {|client, url, params| url =~ /#{model_name}\/#{record.id}$/ }.returns(get_record_xml("#{model_name_for_file(model_name).underscore.singularize}".to_sym, record.id)) end end + + # some models have a parent-child relationship, where you should call: + # Child.find(parent.id) to find items of type child belonging to the parent + # eg. http://developer.xero.com/documentation/payroll-api/leaveapplications/ + def mock_child_relationship_api(child, parent) + mock_api(child) + mock_api(parent) + # grab the ID of each parent record + # if we call api/child/parent_id, return the appropriate child xml + @client.send("#{parent.singularize}".to_sym).all.each do | record | + next if record.id.nil? + client_for_stubbing.stubs(:http_get).with {|client, url, params| + url =~ /#{child}\/#{record.id}$/ + }.returns(get_record_xml("#{model_name_for_file(child).underscore.singularize}".to_sym, record.id)) + end + end def mock_report_api(report_type) client_for_stubbing.stubs(:http_get).with { | client, url, params | url =~ /Reports\/#{report_type}$/ }.returns(get_report_xml(report_type)) diff --git a/test/unit/models/payroll/leave_application_test.rb b/test/unit/models/payroll/leave_application_test.rb index b83d5a58..561db9ab 100644 --- a/test/unit/models/payroll/leave_application_test.rb +++ b/test/unit/models/payroll/leave_application_test.rb @@ -5,18 +5,14 @@ class LeaveApplicationTest < Test::Unit::TestCase def setup @client = Xeroizer::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET).payroll - #mock_api('Employees') - #mock_api('LeaveApplications') + mock_child_relationship_api('LeaveApplications', 'Employees') end -=begin test "can get leave applications using employee ID" do application = @client.LeaveApplication.find(@client.Employee.first.id) assert_not_nil application assert_equal 1, application.leave_periods.size - application.add_leave_periods(number_of_units: 48.00, pay_period_end_date: Date.today) - application.save + application.add_leave_period(number_of_units: 48.00, pay_period_end_date: Date.today) assert_equal 2, application.leave_periods.size end -=end end diff --git a/test/unit/models/payroll/pay_runs_test.rb b/test/unit/models/payroll/pay_runs_test.rb new file mode 100644 index 00000000..e04a614a --- /dev/null +++ b/test/unit/models/payroll/pay_runs_test.rb @@ -0,0 +1,15 @@ +require 'test_helper' + +class PayRunsTest < Test::Unit::TestCase + include TestHelper + + def setup + @client = Xeroizer::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET).payroll + mock_api('PayRuns') + end + + test "get all" do + runs = @client.PayRun.all + assert_equal 2, runs.length + end +end