# frozen_string_literal: truerequire'restforce/concerns/verbs'moduleRestforcemoduleConcernsmoduleCompositeAPIextendRestforce::Concerns::Verbsdefine_verbs:postdefcomposite(all_or_none: false,collate_subrequests: false)subrequests=Subrequests.new(options)yield(subrequests)ifsubrequests.requests.length>25raiseArgumentError,'Cannot have more than 25 subrequests.'endproperties={compositeRequest: subrequests.requests,allOrNone: all_or_none,collateSubrequests: collate_subrequests}response=api_post('composite',properties.to_json)results=response.body['compositeResponse']has_errors=results.any?{|result|result['httpStatusCode'].digits.last==4}ifall_or_none&&has_errorslast_error_index=results.rindex{|result|result['httpStatusCode']!=412}last_error=results[last_error_index]raiseCompositeAPIError.new(last_error['body'][0]['errorCode'],response)endresultsenddefcomposite!(collate_subrequests: false,&block)composite(all_or_none: true,collate_subrequests: collate_subrequests,&block)endclassSubrequestsdefinitialize(options)@options=options@requests=[]endattr_reader:options,:requestsdefcreate(sobject,reference_id,attrs)requests<<{method: 'POST',url: composite_api_path(sobject),body: attrs,referenceId: reference_id}enddefupdate(sobject,reference_id,attrs)id=attrs.fetch(attrs.keys.find{|k,_v|k.to_s.casecmp?('id')},nil)raiseArgumentError,'Id field missing from attrs.'unlessidattrs_without_id=attrs.reject{|k,_v|k.to_s.casecmp?('id')}requests<<{method: 'PATCH',url: composite_api_path("#{sobject}/#{id}"),body: attrs_without_id,referenceId: reference_id}enddefdestroy(sobject,reference_id,id)requests<<{method: 'DELETE',url: composite_api_path("#{sobject}/#{id}"),referenceId: reference_id}enddefupsert(sobject,reference_id,ext_field,attrs)raiseArgumentError,'External id field missing.'unlessext_fieldext_id=attrs.fetch(attrs.keys.finddo|k,_v|k.to_s.casecmp?(ext_field.to_s)end,nil)raiseArgumentError,'External id missing from attrs.'unlessext_idattrs_without_ext_id=attrs.reject{|k,_v|k.to_s.casecmp?(ext_field)}requests<<{method: 'PATCH',url: composite_api_path("#{sobject}/#{ext_field}/#{ext_id}"),body: attrs_without_ext_id,referenceId: reference_id}enddeffind(sobject,reference_id,id)requests<<{method: 'GET',url: composite_api_path("#{sobject}/#{id}"),referenceId: reference_id}endprivatedefcomposite_api_path(path)"/services/data/v#{options[:api_version]}/sobjects/#{path}"endendendendend