Files
contractor/differ.cfm
T

81 lines
4.9 KiB
Plaintext

<cfsetting showdebugoutput="no" enablecfoutputonly="true">
<cfheader name="Content-Type" value="application/json; charset=utf-8">
<cfparam name="url.contract_id" default="">
<cfset result = {ok: false, error: ""}>
<cftry>
<cfif NOT len(url.contract_id)>
<cfset result.error = "contract_id required">
<cfelse>
<cfquery name="initSup" datasource="baza">
SELECT id FROM supplements WHERE contract_id=<cfqueryparam value="#url.contract_id#" cfsqltype="cf_sql_varchar"> AND type='initial' ORDER BY created_at LIMIT 1
</cfquery>
<cfif initSup.recordCount EQ 0>
<cfquery name="initSup" datasource="baza">
SELECT id FROM supplements WHERE contract_id=<cfqueryparam value="#url.contract_id#" cfsqltype="cf_sql_varchar"> ORDER BY created_at LIMIT 1
</cfquery>
</cfif>
<cfquery name="amendments" datasource="baza">
SELECT id, type FROM supplements WHERE contract_id=<cfqueryparam value="#url.contract_id#" cfsqltype="cf_sql_varchar"> AND id!=<cfqueryparam value="#initSup.id#" cfsqltype="cf_sql_varchar"> ORDER BY created_at
</cfquery>
<cfif amendments.recordCount EQ 0>
<cfset result.error = "no amendments">
<cfelse>
<cfquery name="rInit" datasource="baza">
SELECT row_num, name, price, qty, sum, date_start FROM spec_rows WHERE supplement_id=<cfqueryparam value="#initSup.id#" cfsqltype="cf_sql_varchar"> ORDER BY row_num
</cfquery>
<cfset initByNum = {}>
<cfloop query="rInit">
<cfset initByNum[rInit.row_num] = {name: rInit.name, price: rInit.price, qty: rInit.qty, sum: rInit.sum, date_start: rInit.date_start}>
</cfloop>
<cfset allChanges = []>
<cfset fields = ["name","price","qty","sum","date_start"]>
<cfloop query="amendments">
<cfquery name="rAmd" datasource="baza">
SELECT row_num, name, price, qty, sum, date_start FROM spec_rows WHERE supplement_id=<cfqueryparam value="#amendments.id#" cfsqltype="cf_sql_varchar"> ORDER BY row_num
</cfquery>
<cfset amdByNum = {}>
<cfloop query="rAmd">
<cfset amdByNum[rAmd.row_num] = {name: rAmd.name, price: rAmd.price, qty: rAmd.qty, sum: rAmd.sum, date_start: rAmd.date_start}>
</cfloop>
<cfset allNums = structKeyArray(initByNum)>
<cfloop array="#structKeyArray(amdByNum)#" index="n">
<cfif NOT structKeyExists(initByNum, n)><cfset arrayAppend(allNums, n)></cfif>
</cfloop>
<cfset arraySort(allNums, "numeric")>
<cfset changes = []>
<cfloop array="#allNums#" index="num">
<cfset inOld = structKeyExists(initByNum, num)>
<cfset inNew = structKeyExists(amdByNum, num)>
<cfif inOld AND NOT inNew>
<cfset arrayAppend(changes, {row_num:num, change_type:"deleted", old_values:initByNum[num], new_values:{}})>
<cfelseif NOT inOld AND inNew>
<cfset arrayAppend(changes, {row_num:num, change_type:"added", old_values:{}, new_values:amdByNum[num]})>
<cfelse>
<cfset ov = initByNum[num]>
<cfset nv = amdByNum[num]>
<cfset same = true>
<cfset cf = {}>
<cfloop array="#fields#" index="f">
<cfif structKeyExists(ov,f) AND structKeyExists(nv,f)>
<cfif toString(ov[f]) NEQ toString(nv[f])>
<cfset same = false><cfset cf[f] = {old:ov[f], new:nv[f]}>
</cfif>
<cfelseif structKeyExists(ov,f) OR structKeyExists(nv,f)>
<cfset same = false><cfset cf[f] = {old: structKeyExists(ov,f)?ov[f]:"", new: structKeyExists(nv,f)?nv[f]:""}>
</cfif>
</cfloop>
<cfset arrayAppend(changes, {row_num:num, change_type:same?"unchanged":"changed", old_values:ov, new_values:nv, changed_fields:cf})>
</cfif>
</cfloop>
<cfset sm = {added:0, deleted:0, changed:0, unchanged:0}>
<cfloop array="#changes#" index="ch"><cfset sm[ch.change_type] = sm[ch.change_type] + 1></cfloop>
<cfset arrayAppend(allChanges, {supplement_id:amendments.id, type:amendments.type, changes:changes, summary:sm})>
</cfloop>
<cfset result = {ok:true, contract_id:url.contract_id, initial_id:initSup.id, all_changes:allChanges}>
</cfif>
</cfif>
<cfcatch><cfset result = {ok:false, error:cfcatch.message, detail:cfcatch.detail}></cfcatch>
</cftry>
<cfoutput>#serializeJSON(result)#</cfoutput>