$cfg) { $dtoField = $cfg['dto']; $mapped[$dtoField] = self::transformValue( $after[$misField] ?? null, $cfg['type'] ); } // audit $mapped['cusSourceType'] = 'MIS'; return $mapped; } private static function mapPatch($payload) { $before = $payload['before'] ?? []; $after = $payload['after'] ?? []; $patch = []; foreach (self::fieldMap() as $misField => $cfg) { $beforeVal = $before[$misField] ?? null; $afterVal = $after[$misField] ?? null; if (!self::isDifferent($beforeVal, $afterVal)) { continue; } $patch[$cfg['dto']] = self::transformValue( $afterVal, $cfg['type'] ); } // NO CHANGE if (count($patch) <= 0) { return null; } // REQUIRED $patch['cusSourceType'] = 'MIS'; $patch['cusNo'] = $after['c_accountno'] ?? null; $patch['cusExternalUpdatedBy'] = $after['c_updatedby'] ?? null; return $patch; } // FIELD MAP private static function fieldMap(): array { return [ 'c_accountno' => ['dto' => 'cusNo' , 'type' => 'string'], 'c_name' => ['dto' => 'cusName' , 'type' => 'string'], 'c_status' => ['dto' => 'cusStatus' , 'type' => 'string'], 'c_regionuid' => ['dto' => 'cusRegionId' , 'type' => 'int'], 'c_area' => ['dto' => 'cusAreaId' , 'type' => 'int'], 'c_address' => ['dto' => 'cusAddress1' , 'type' => 'string'], 'c_location' => ['dto' => 'cusAddress2' , 'type' => 'string'], 'c_postal' => ['dto' => 'cusPostalCode' , 'type' => 'string'], 'c_city' => ['dto' => 'cusCity' , 'type' => 'string'], 'c_province' => ['dto' => 'cusProvince' , 'type' => 'string'], 'c_geolat' => ['dto' => 'cusGeoLat' , 'type' => 'float'], 'c_geolon' => ['dto' => 'cusGeoLon' , 'type' => 'float'], 'c_email' => ['dto' => 'cusEmail' , 'type' => 'string'], 'c_phone' => ['dto' => 'cusPhone' , 'type' => 'string'], 'c_phoneext' => ['dto' => 'cusPhoneExt' , 'type' => 'string'], 'c_contractdate' => ['dto' => 'cusContractDate' , 'type' => 'date'], 'c_contractby' => ['dto' => 'cusContractedBy' , 'type' => 'string'], 'c_installdate' => ['dto' => 'cusInstallDate' , 'type' => 'date'], // 'c_fullcycle' => ['dto' => 'cusFullCycle' , 'type' => 'decimal'], // 'c_fullcycleflag' => ['dto' => 'cusFullCycleFlag' , 'type' => 'bool'], // 'c_fullcycleforced' => ['dto' => 'cusFullCycleForced' , 'type' => 'decimal'], // 'c_forceddate' => ['dto' => 'cusFullCycleForcedDate' , 'type' => 'date'], 'c_schedule' => ['dto' => 'cusSchedule' , 'type' => 'string'], 'c_scheduleday' => ['dto' => 'cusScheduledays' , 'type' => 'string'], 'c_lastpaiddate' => ['dto' => 'cusLastPaidDate' , 'type' => 'date'], 'c_rate' => ['dto' => 'cusRate' , 'type' => 'float'], 'c_paymenttype' => ['dto' => 'cusPayMethod' , 'type' => 'string'], 'c_form_eu' => ['dto' => 'cusIsccDate' , 'type' => 'date'], 'c_form_corsia' => ['dto' => 'cusCorsiaDate' , 'type' => 'date'], 'c_hstno' => ['dto' => 'cusHstNo' , 'type' => 'string'], 'c_inactivedate' => ['dto' => 'cusTerminatedDate' , 'type' => 'date'], 'c_lastpickupdate' => ['dto' => 'cusLastPickupDate' , 'type' => 'date'], 'c_lastpickupquantity' => ['dto' => 'cusLastPickupQty' , 'type' => 'int'], 'c_sludge' => ['dto' => 'cusLastSludge' , 'type' => 'int'], 'c_comment_ri' => ['dto' => 'cusComment' , 'type' => 'string'], 'c_comment_ci' => ['dto' => 'cusContactComment' , 'type' => 'string'], 'c_createdby' => ['dto' => 'cusExternalCreatedBy' , 'type' => 'string'], 'c_updatedby' => ['dto' => 'cusExternalUpdatedBy' , 'type' => 'string'], 'c_salesperson' => ['dto' => 'cusSalesperson' , 'type' => 'string'], 'c_salescommissiondate' => ['dto' => 'cusSalesCommissionDate' , 'type' => 'string'], 'c_salesmethod' => ['dto' => 'cusSalesMethod' , 'type' => 'string'], // 어차피 무시당함 // 'c_createddate' => ['dto' => 'cusCreatedAt' , 'type' => 'datetime'], // 'c_updateddate' => ['dto' => 'cusUpdatedAt' , 'type' => 'datetime'], ]; } // VALUE TRANSFORM private static function transformValue( $value, string $type ) { switch ($type) { case 'int': return ($value === ''||$value === null) ? null : (int)$value; case 'float': return ($value === ''||$value === null) ? null : (float)$value; case 'decimal': return ($value === ''||$value === null) ? null : (float)$value; case 'bool': return ($value == '1'||$value === 1||$value === true); case 'date': return self::date($value); case 'datetime': return self::datetime($value); default: return ($value === null) ? null : rtrim((string)$value); } } private static function isDifferent($a, $b): bool { if (is_numeric($a) && is_numeric($b)) { return (float)$a != (float)$b; } return $a !== $b; } private static function date($value) { $value = trim((string)$value); if ($value == '') { return null; } $value = preg_replace('/[^0-9]/','',$value); if (strlen($value) != 8) { return null; } return substr($value, 0, 4) . '-' . substr($value, 4, 2) . '-' . substr($value, 6, 2); } private static function datetime($yyyymmddhhmiss) { if ( empty($yyyymmddhhmiss) || strlen($yyyymmddhhmiss) != 14 ) { return null; } return substr($yyyymmddhhmiss,0,4)."-". substr($yyyymmddhhmiss,4,2)."-". substr($yyyymmddhhmiss,6,2)."T". substr($yyyymmddhhmiss,8,2).":". substr($yyyymmddhhmiss,10,2).":". substr($yyyymmddhhmiss,12,2); } }