chore: add spec-kit and standardize signatures
- Added GitHub spec-kit for development workflow - Standardized file signatures to Descomplicar® format - Updated development configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
@@ -183,7 +188,7 @@ class ClientSyncService
|
||||
{
|
||||
try {
|
||||
// Transform Moloni data to Perfex format
|
||||
$perfex_data = $this->transform_moloni_to_perfex($moloni_client);
|
||||
$perfex_data = $this->customer_mapper->toPerfex($moloni_client);
|
||||
|
||||
// Check if client already exists
|
||||
$existing_mapping = $this->mapping_model->get_by_moloni_id('client', $moloni_client['id']);
|
||||
@@ -442,7 +447,7 @@ class ClientSyncService
|
||||
$contact = $moloni_client['contact_info'];
|
||||
$perfex_data['mobile'] = $contact['mobile'] ?? '';
|
||||
$perfex_data['fax'] = $contact['fax'] ?? '';
|
||||
$perfex_data['alternative_email'] = $contact['alternative_email'] ?? '';
|
||||
$perfex_data['alternative_email'] = $contact['alternative_email'] ?? ''
|
||||
}
|
||||
|
||||
// Preferences mapping
|
||||
@@ -720,7 +725,7 @@ class ClientSyncService
|
||||
*/
|
||||
private function create_moloni_client($perfex_client, $options = [])
|
||||
{
|
||||
$moloni_data = $this->transform_perfex_to_moloni($perfex_client);
|
||||
$moloni_data = $this->customer_mapper->toMoloni($perfex_client);
|
||||
|
||||
// Mock API response for testing
|
||||
$moloni_response = [
|
||||
@@ -755,7 +760,7 @@ class ClientSyncService
|
||||
private function update_moloni_client($perfex_client, $mapping, $options = [])
|
||||
{
|
||||
$moloni_client_id = $mapping['moloni_id'];
|
||||
$moloni_data = $this->transform_perfex_to_moloni($perfex_client);
|
||||
$moloni_data = $this->customer_mapper->toMoloni($perfex_client);
|
||||
|
||||
// Mock API response for testing
|
||||
$moloni_response = [
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
/**
|
||||
* AES-256-GCM Encryption Helper for Desk-Moloni v3.0
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
@@ -35,19 +40,51 @@ class PerfexHooks
|
||||
public function __construct()
|
||||
{
|
||||
$this->CI = &get_instance();
|
||||
// Load base model if available; ignore if not to avoid fatal
|
||||
|
||||
// Load base model for local use
|
||||
if (method_exists($this->CI, 'load')) {
|
||||
$this->CI->load->model('desk_moloni/desk_moloni_sync_log_model', 'desk_moloni_sync_log_model');
|
||||
$this->model = $this->CI->desk_moloni_sync_log_model;
|
||||
}
|
||||
|
||||
$this->queue_processor = new QueueProcessor();
|
||||
|
||||
// Initialize dependencies for QueueProcessor
|
||||
$this->CI->load->model('desk_moloni/desk_moloni_model');
|
||||
$model = $this->CI->desk_moloni_model;
|
||||
|
||||
// Redis initialization
|
||||
if (!extension_loaded('redis')) {
|
||||
throw new \Exception('Redis extension not loaded');
|
||||
}
|
||||
$redis = new \Redis();
|
||||
$redis_host = get_option('desk_moloni_redis_host', '127.0.0.1');
|
||||
$redis_port = (int)get_option('desk_moloni_redis_port', 6379);
|
||||
$redis_password = get_option('desk_moloni_redis_password', '');
|
||||
$redis_db = (int)get_option('desk_moloni_redis_db', 0);
|
||||
if (!$redis->connect($redis_host, $redis_port, 2.5)) {
|
||||
throw new \Exception('Failed to connect to Redis server');
|
||||
}
|
||||
if (!empty($redis_password)) {
|
||||
$redis->auth($redis_password);
|
||||
}
|
||||
$redis->select($redis_db);
|
||||
|
||||
// Instantiate services
|
||||
$this->entity_mapping = new EntityMappingService();
|
||||
$this->error_handler = new ErrorHandler();
|
||||
|
||||
$retry_handler = new RetryHandler();
|
||||
|
||||
// Instantiate QueueProcessor with dependencies
|
||||
$this->queue_processor = new QueueProcessor(
|
||||
$redis,
|
||||
$model,
|
||||
$this->entity_mapping,
|
||||
$this->error_handler,
|
||||
$retry_handler
|
||||
);
|
||||
|
||||
$this->register_hooks();
|
||||
|
||||
log_activity('PerfexHooks initialized and registered');
|
||||
|
||||
log_activity('PerfexHooks initialized and registered with DI');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
@@ -15,13 +20,12 @@ defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
class QueueProcessor
|
||||
{
|
||||
protected $CI;
|
||||
protected $redis;
|
||||
protected $model;
|
||||
protected $entity_mapping;
|
||||
protected $error_handler;
|
||||
protected $retry_handler;
|
||||
|
||||
|
||||
// Queue configuration
|
||||
const REDIS_PREFIX = 'desk_moloni:queue:';
|
||||
const QUEUE_MAIN = 'main';
|
||||
@@ -29,20 +33,20 @@ class QueueProcessor
|
||||
const QUEUE_DELAY = 'delay';
|
||||
const QUEUE_DEAD_LETTER = 'dead_letter';
|
||||
const QUEUE_PROCESSING = 'processing';
|
||||
|
||||
|
||||
// Queue priorities
|
||||
const PRIORITY_LOW = 1;
|
||||
const PRIORITY_NORMAL = 2;
|
||||
const PRIORITY_HIGH = 3;
|
||||
const PRIORITY_CRITICAL = 4;
|
||||
|
||||
|
||||
// Processing status
|
||||
const STATUS_PENDING = 'pending';
|
||||
const STATUS_PROCESSING = 'processing';
|
||||
const STATUS_COMPLETED = 'completed';
|
||||
const STATUS_FAILED = 'failed';
|
||||
const STATUS_RETRYING = 'retrying';
|
||||
|
||||
|
||||
// Retry configuration
|
||||
const MAX_ATTEMPTS = 5;
|
||||
const RETRY_DELAYS = [30, 120, 300, 900, 1800]; // 30s, 2m, 5m, 15m, 30m
|
||||
@@ -50,55 +54,25 @@ class QueueProcessor
|
||||
const MEMORY_LIMIT = 512 * 1024 * 1024; // 512MB
|
||||
const TIME_LIMIT = 300; // 5 minutes
|
||||
const PROCESSING_TIMEOUT = 600; // 10 minutes
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->CI = &get_instance();
|
||||
$this->CI->load->model('desk_moloni_model');
|
||||
$this->model = $this->CI->desk_moloni_model;
|
||||
|
||||
// Initialize Redis connection
|
||||
$this->init_redis();
|
||||
|
||||
// Initialize supporting services
|
||||
$this->entity_mapping = new EntityMappingService();
|
||||
$this->error_handler = new ErrorHandler();
|
||||
$this->retry_handler = new RetryHandler();
|
||||
|
||||
|
||||
public function __construct(
|
||||
\Redis $redis,
|
||||
Desk_moloni_model $model,
|
||||
EntityMappingService $entity_mapping,
|
||||
ErrorHandler $error_handler,
|
||||
RetryHandler $retry_handler
|
||||
) {
|
||||
$this->redis = $redis;
|
||||
$this->model = $model;
|
||||
$this->entity_mapping = $entity_mapping;
|
||||
$this->error_handler = $error_handler;
|
||||
$this->retry_handler = $retry_handler;
|
||||
|
||||
// Set memory and time limits
|
||||
ini_set('memory_limit', '512M');
|
||||
set_time_limit(self::TIME_LIMIT);
|
||||
|
||||
log_activity('Enhanced QueueProcessor initialized with Redis backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Redis connection
|
||||
*/
|
||||
protected function init_redis()
|
||||
{
|
||||
if (!extension_loaded('redis')) {
|
||||
throw new \Exception('Redis extension not loaded');
|
||||
}
|
||||
|
||||
$this->redis = new \Redis();
|
||||
|
||||
$redis_host = get_option('desk_moloni_redis_host', '127.0.0.1');
|
||||
$redis_port = (int)get_option('desk_moloni_redis_port', 6379);
|
||||
$redis_password = get_option('desk_moloni_redis_password', '');
|
||||
$redis_db = (int)get_option('desk_moloni_redis_db', 0);
|
||||
|
||||
if (!$this->redis->connect($redis_host, $redis_port, 2.5)) {
|
||||
throw new \Exception('Failed to connect to Redis server');
|
||||
}
|
||||
|
||||
if (!empty($redis_password)) {
|
||||
$this->redis->auth($redis_password);
|
||||
}
|
||||
|
||||
$this->redis->select($redis_db);
|
||||
|
||||
log_activity("Connected to Redis server at {$redis_host}:{$redis_port}");
|
||||
|
||||
log_activity('Enhanced QueueProcessor initialized with dependency injection');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
267
modules/desk_moloni/libraries/mappers/CustomerMapper.php
Normal file
267
modules/desk_moloni/libraries/mappers/CustomerMapper.php
Normal file
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Customer Data Mapper
|
||||
*
|
||||
* Handles the transformation of client/customer data between Perfex CRM and Moloni formats.
|
||||
*
|
||||
* @package DeskMoloni\Libraries\Mappers
|
||||
* @version 1.0.0
|
||||
* @author Descomplicar®
|
||||
*/
|
||||
class CustomerMapper
|
||||
{
|
||||
private $CI;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->CI = &get_instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform Perfex client data to Moloni format
|
||||
*
|
||||
* @param array $perfex_client Perfex client data
|
||||
* @return array Moloni client data
|
||||
*/
|
||||
public function toMoloni($perfex_client)
|
||||
{
|
||||
// Basic client information with comprehensive field mappings
|
||||
$moloni_data = [
|
||||
'name' => $perfex_client['company'] ?: trim($perfex_client['firstname'] . ' ' . $perfex_client['lastname']),
|
||||
'email' => $perfex_client['email'],
|
||||
'phone' => $perfex_client['phonenumber'],
|
||||
'website' => $perfex_client['website'],
|
||||
'vat' => $perfex_client['vat'],
|
||||
'number' => $perfex_client['vat'] ?: $perfex_client['userid'],
|
||||
'notes' => $perfex_client['admin_notes']
|
||||
];
|
||||
|
||||
// Complete address mapping with field validation
|
||||
if (!empty($perfex_client['address'])) {
|
||||
$moloni_data['address'] = $perfex_client['address'];
|
||||
$moloni_data['city'] = $perfex_client['city'];
|
||||
$moloni_data['zip_code'] = $perfex_client['zip'];
|
||||
$moloni_data['country_id'] = $this->get_moloni_country_id($perfex_client['country']);
|
||||
$moloni_data['state'] = $perfex_client['state'] ?? '';
|
||||
}
|
||||
|
||||
// Shipping address mapping
|
||||
if (!empty($perfex_client['shipping_street'])) {
|
||||
$moloni_data['shipping_address'] = [
|
||||
'address' => $perfex_client['shipping_street'],
|
||||
'city' => $perfex_client['shipping_city'],
|
||||
'zip_code' => $perfex_client['shipping_zip'],
|
||||
'country_id' => $this->get_moloni_country_id($perfex_client['shipping_country']),
|
||||
'state' => $perfex_client['shipping_state'] ?? ''
|
||||
];
|
||||
}
|
||||
|
||||
// Contact information mapping
|
||||
$moloni_data['contact_info'] = [
|
||||
'primary_contact' => trim($perfex_client['firstname'] . ' ' . $perfex_client['lastname']),
|
||||
'phone' => $perfex_client['phonenumber'],
|
||||
'mobile' => $perfex_client['mobile'] ?? '',
|
||||
'fax' => $perfex_client['fax'] ?? '',
|
||||
'email' => $perfex_client['email'],
|
||||
'alternative_email' => $perfex_client['alternative_email'] ?? ''
|
||||
];
|
||||
|
||||
// Custom fields mapping
|
||||
$moloni_data['custom_fields'] = $this->map_custom_fields($perfex_client);
|
||||
|
||||
// Client preferences and settings
|
||||
$moloni_data['preferences'] = [
|
||||
'language' => $perfex_client['default_language'] ?? 'pt',
|
||||
'currency' => $perfex_client['default_currency'] ?? 'EUR',
|
||||
'payment_terms' => $perfex_client['payment_terms'] ?? 30,
|
||||
'credit_limit' => $perfex_client['credit_limit'] ?? 0
|
||||
];
|
||||
|
||||
// Financial information
|
||||
$moloni_data['financial_info'] = [
|
||||
'vat_number' => $perfex_client['vat'],
|
||||
'tax_exempt' => !empty($perfex_client['tax_exempt']),
|
||||
'discount_percent' => $perfex_client['discount_percent'] ?? 0,
|
||||
'billing_cycle' => $perfex_client['billing_cycle'] ?? 'monthly'
|
||||
];
|
||||
|
||||
return array_filter($moloni_data, function($value) {
|
||||
return $value !== null && $value !== '';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform Moloni client data to Perfex format
|
||||
*
|
||||
* @param array $moloni_client Moloni client data
|
||||
* @return array Perfex client data
|
||||
*/
|
||||
public function toPerfex($moloni_client)
|
||||
{
|
||||
// Parse name into first and last name if it's a person
|
||||
$name_parts = explode(' ', $moloni_client['name'], 2);
|
||||
$is_company = isset($moloni_client['is_company']) ? $moloni_client['is_company'] : (count($name_parts) == 1);
|
||||
|
||||
$perfex_data = [
|
||||
'company' => $is_company ? $moloni_client['name'] : '',
|
||||
'firstname' => !$is_company ? $name_parts[0] : '',
|
||||
'lastname' => !$is_company && isset($name_parts[1]) ? $name_parts[1] : '',
|
||||
'email' => $moloni_client['email'] ?? '',
|
||||
'phonenumber' => $moloni_client['phone'] ?? '',
|
||||
'website' => $moloni_client['website'] ?? '',
|
||||
'vat' => $moloni_client['vat'] ?? '',
|
||||
'admin_notes' => $moloni_client['notes'] ?? ''
|
||||
];
|
||||
|
||||
// Address mapping from Moloni to Perfex
|
||||
if (!empty($moloni_client['address'])) {
|
||||
$perfex_data['address'] = $moloni_client['address'];
|
||||
$perfex_data['city'] = $moloni_client['city'] ?? '';
|
||||
$perfex_data['zip'] = $moloni_client['zip_code'] ?? '';
|
||||
$perfex_data['state'] = $moloni_client['state'] ?? '';
|
||||
$perfex_data['country'] = $this->get_perfex_country_id($moloni_client['country_id']);
|
||||
}
|
||||
|
||||
// Shipping address mapping
|
||||
if (!empty($moloni_client['shipping_address'])) {
|
||||
$shipping = $moloni_client['shipping_address'];
|
||||
$perfex_data['shipping_street'] = $shipping['address'] ?? '';
|
||||
$perfex_data['shipping_city'] = $shipping['city'] ?? '';
|
||||
$perfex_data['shipping_zip'] = $shipping['zip_code'] ?? '';
|
||||
$perfex_data['shipping_state'] = $shipping['state'] ?? '';
|
||||
$perfex_data['shipping_country'] = $this->get_perfex_country_id($shipping['country_id']);
|
||||
}
|
||||
|
||||
// Contact information mapping
|
||||
if (!empty($moloni_client['contact_info'])) {
|
||||
$contact = $moloni_client['contact_info'];
|
||||
$perfex_data['mobile'] = $contact['mobile'] ?? '';
|
||||
$perfex_data['fax'] = $contact['fax'] ?? '';
|
||||
$perfex_data['alternative_email'] = $contact['alternative_email'] ?? '';
|
||||
}
|
||||
|
||||
// Preferences mapping
|
||||
if (!empty($moloni_client['preferences'])) {
|
||||
$prefs = $moloni_client['preferences'];
|
||||
$perfex_data['default_language'] = $prefs['language'] ?? 'portuguese';
|
||||
$perfex_data['default_currency'] = $prefs['currency'] ?? 'EUR';
|
||||
$perfex_data['payment_terms'] = $prefs['payment_terms'] ?? 30;
|
||||
$perfex_data['credit_limit'] = $prefs['credit_limit'] ?? 0;
|
||||
}
|
||||
|
||||
// Financial information mapping
|
||||
if (!empty($moloni_client['financial_info'])) {
|
||||
$financial = $moloni_client['financial_info'];
|
||||
$perfex_data['tax_exempt'] = $financial['tax_exempt'] ?? false;
|
||||
$perfex_data['discount_percent'] = $financial['discount_percent'] ?? 0;
|
||||
$perfex_data['billing_cycle'] = $financial['billing_cycle'] ?? 'monthly';
|
||||
}
|
||||
|
||||
// Map custom fields back to Perfex
|
||||
if (!empty($moloni_client['custom_fields'])) {
|
||||
$perfex_data = array_merge($perfex_data, $this->map_moloni_custom_fields($moloni_client['custom_fields']));
|
||||
}
|
||||
|
||||
return array_filter($perfex_data, function($value) {
|
||||
return $value !== null && $value !== '';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Perfex custom fields to Moloni format with custom mapping support
|
||||
*/
|
||||
private function map_custom_fields($perfex_client)
|
||||
{
|
||||
$custom_fields = [];
|
||||
|
||||
// Load custom fields for clients with field mapping
|
||||
$this->CI->load->model('custom_fields_model');
|
||||
$client_custom_fields = $this->CI->custom_fields_model->get('clients');
|
||||
|
||||
foreach ($client_custom_fields as $field) {
|
||||
$field_name = 'custom_fields[' . $field['id'] . ']';
|
||||
if (isset($perfex_client[$field_name])) {
|
||||
// Custom field mapping with field mapping support
|
||||
$custom_fields[$field['name']] = [
|
||||
'value' => $perfex_client[$field_name],
|
||||
'type' => $field['type'],
|
||||
'required' => $field['required'],
|
||||
'mapped_to_moloni' => $this->get_moloni_field_mapping($field['name'])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $custom_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Moloni field mapping for custom fields
|
||||
*/
|
||||
private function get_moloni_field_mapping($perfex_field_name)
|
||||
{
|
||||
// Field mapping configuration
|
||||
$field_mappings = [
|
||||
'company_size' => 'empresa_dimensao',
|
||||
'industry' => 'setor_atividade',
|
||||
'registration_number' => 'numero_registo',
|
||||
'tax_id' => 'numero_fiscal'
|
||||
];
|
||||
|
||||
return $field_mappings[strtolower($perfex_field_name)] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Moloni custom fields back to Perfex format
|
||||
*/
|
||||
private function map_moloni_custom_fields($moloni_custom_fields)
|
||||
{
|
||||
$perfex_fields = [];
|
||||
|
||||
// This would need to be implemented based on your specific custom field mapping strategy
|
||||
foreach ($moloni_custom_fields as $field_name => $field_data) {
|
||||
// Map back to Perfex custom field format
|
||||
$perfex_fields['moloni_' . $field_name] = $field_data['value'];
|
||||
}
|
||||
|
||||
return $perfex_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Moloni country ID from country name/code
|
||||
*/
|
||||
private function get_moloni_country_id($country)
|
||||
{
|
||||
if (empty($country)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$country_mappings = [
|
||||
'Portugal' => 1, 'PT' => 1,
|
||||
'Spain' => 2, 'ES' => 2,
|
||||
'France' => 3, 'FR' => 3
|
||||
];
|
||||
|
||||
return $country_mappings[$country] ?? 1; // Default to Portugal
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Perfex country ID from Moloni country ID
|
||||
*/
|
||||
private function get_perfex_country_id($moloni_country_id)
|
||||
{
|
||||
$country_mappings = [
|
||||
1 => 'PT', // Portugal
|
||||
2 => 'ES', // Spain
|
||||
3 => 'FR' // France
|
||||
];
|
||||
|
||||
return $country_mappings[$moloni_country_id] ?? 'PT';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user