Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public function syncdata()
- {
- try {
- $invoice_ids = $this->input->post('invoice_id');
- if (empty($invoice_ids)) {
- return $this->_json_error('Tidak ada invoice yang dipilih');
- }
- $invoice_ids = is_array($invoice_ids) ? $invoice_ids : explode(',', $invoice_ids);
- $invoice_ids = array_filter(array_map('trim', $invoice_ids));
- // Validasi max 10
- if (count($invoice_ids) > 10) {
- return $this->_json_error('Maksimal 10 invoice per sinkronisasi');
- }
- $result = [
- 'success_count' => 0,
- 'failed_count' => 0,
- 'failed' => []
- ];
- foreach ($invoice_ids as $id) {
- $res = $this->process_invoice_simple($id);
- if ($res['success']) {
- $result['success_count']++;
- } else {
- $result['failed_count']++;
- $result['failed'][] = [
- 'invoice_id' => $id,
- 'message' => $res['message']
- ];
- }
- }
- return $this->output
- ->set_content_type('application/json')
- ->set_output(json_encode($result));
- } catch (Exception $e) {
- return $this->_json_error('Error: ' . $e->getMessage());
- }
- }
- private function extract_error_simple($response)
- {
- if (!empty($response['response']['error_full_messages'])) {
- return is_array($response['response']['error_full_messages'])
- ? implode(' | ', $response['response']['error_full_messages'])
- : $response['response']['error_full_messages'];
- }
- if (!empty($response['response']['error'])) {
- return $response['response']['error'];
- }
- if (!empty($response['response']['message'])) {
- return $response['response']['message'];
- }
- return 'Unknown error. HTTP Code: ' . ($response['http_code'] ?? 'N/A');
- }
- private function _json_error($message)
- {
- return $this->output
- ->set_content_type('application/json')
- ->set_output(json_encode([
- 'success' => false,
- 'message' => $message
- ]));
- }
- private function check_customer($invoice)
- {
- // Jika customer sudah ada Jurnal ID, pakai yang ada
- $pelanggan_jurnal_id = $invoice->pelanggan_jurnal_id;
- if (!empty($pelanggan_jurnal_id)) {
- // Verifikasi customer masih ada di Mekari
- $verify_result = $this->verify_customer_exists($pelanggan_jurnal_id);
- if ($verify_result['success']) {
- return [
- 'success' => true,
- 'pelanggan_jurnal_id' => $pelanggan_jurnal_id
- ];
- }
- }
- // Cek apakah customer sudah ada di Mekari berdasarkan nama
- $customer_name = !empty($invoice->pelanggan_jurnal_nama) ? $invoice->pelanggan_jurnal_nama : $invoice->pelanggan_nama;
- try {
- // 1. SEARCH CUSTOMER BY NAME
- $response = $this->mekari_jurnal->request(
- 'GET',
- '/public/jurnal/api/v1/contacts',
- [ 'type' => 'customer', 'name' => trim($customer_name) ]
- );
- $contacts = [];
- if (isset($response['response']['contacts']) && is_array($response['response']['contacts'])) {
- $contacts = $response['response']['contacts'];
- }
- if (isset($response['response']['contact_list']['contact_data']) && is_array($response['response']['contact_list']['contact_data'])) {
- $contacts = $response['response']['contact_list']['contact_data'];
- }
- if (!empty($contacts)) {
- $first = $contacts[0];
- $pelanggan_jurnal_id = $first['id'] ?? $first['contact_id'] ?? null;
- $pelanggan_jurnal_nama = $first['display_name'] ?? $first['name'] ?? $customer_name;
- return ['success' => true, 'pelanggan_jurnal_id' => $pelanggan_jurnal_id];
- }
- // 2. BUAT CUSTOMER BARU
- $email = strtolower(trim($invoice->pelanggan_email ?? ''));
- if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
- }
- $payload = [
- 'person' => [
- 'display_name' => $customer_name,
- 'first_name' => $customer_name,
- 'is_customer' => true,
- 'people_type' => 'customer',
- 'email' => $email,
- 'phone' => $invoice->pelanggan_telp ?? '',
- 'address' => $invoice->pelanggan_alamat ?? '',
- 'notes' => 'Created from ISKNet.id'
- ]
- ];
- $create = $this->mekari_jurnal->request(
- 'POST',
- '/public/jurnal/api/v1/contacts',
- $payload
- );
- // Check different possible response structures
- $pelanggan_jurnal_id = null;
- $pelanggan_jurnal_nama = null;
- if (isset($create['response']['person']['id'])) {
- $pelanggan_jurnal_id = $create['response']['person']['id'];
- $pelanggan_jurnal_nama = $create['response']['person']['display_name'] ?? $customer_name;
- }
- elseif (isset($create['response']['contact']['id'])) {
- $pelanggan_jurnal_id = $create['response']['contact']['id'];
- $pelanggan_jurnal_nama = $create['response']['contact']['display_name'] ?? $customer_name;
- }
- elseif (isset($create['response']['id'])) {
- $pelanggan_jurnal_id = $create['response']['id'];
- $pelanggan_jurnal_nama = $customer_name;
- }
- elseif (isset($create['response']['data']['id'])) {
- $pelanggan_jurnal_id = $create['response']['data']['id'];
- $pelanggan_jurnal_nama = $customer_name;
- }
- if ($pelanggan_jurnal_id) {
- // Update database Pelanggan
- $this->db->where('pelanggan_id', $invoice->pelanggan_id)->update('sid_pelanggan', [
- 'pelanggan_jurnal_id' => $pelanggan_jurnal_id,
- 'pelanggan_jurnal_nama' => $pelanggan_jurnal_nama,
- 'pelanggan_update' => date('Y-m-d H:i:s'),
- 'pelanggan_jurnal_response' => json_encode($create['response'])
- ]);
- return ['success' => true, 'pelanggan_jurnal_id' => $pelanggan_jurnal_id];
- } else {
- sleep(1);
- $search_again = $this->mekari_jurnal->request(
- 'GET',
- '/public/jurnal/api/v1/contacts',
- [ 'type' => 'customer', 'name' => trim($customer_name) ]
- );
- if (isset($search_again['response']['contacts'][0]['id'])) {
- $jurnal_id = $search_again['response']['contacts'][0]['id'];
- $this->db->where('pelanggan_id', $invoice->pelanggan_id)->update('sid_pelanggan', [
- 'pelanggan_jurnal_id' => $pelanggan_jurnal_id,
- 'pelanggan_jurnal_nama' => $customer_name,
- 'pelanggan_update' => date('Y-m-d H:i:s'),
- 'pelanggan_jurnal_response' => json_encode($search_again['response'])
- ]);
- return ['success' => true, 'pelanggan_jurnal_id' => $pelanggan_jurnal_id];
- }
- return [
- 'success' => false,
- 'message' => 'Gagal buat Customer Baru di Mekari. Response : ' . json_encode($create['response'] ?? [])
- ];
- }
- } catch (Exception $e) {
- error_log("Customer sync exception: " . $e->getMessage());
- return ['success' => false, 'message' => 'Customer sync error: ' . $e->getMessage()];
- }
- }
- private function verify_customer_exists($pelanggan_jurnal_id)
- {
- try {
- $response = $this->mekari_jurnal->request(
- 'GET',
- '/public/jurnal/api/v1/contacts/' . $pelanggan_jurnal_id
- );
- return ['success' => ($response['http_code'] ?? 0) === 200];
- } catch (Exception $e) {
- return ['success' => false, 'message' => $e->getMessage()];
- }
- }
- private function process_invoice_simple($invoice_id)
- {
- try {
- // 1. CEK INVOICE DI DATABASE
- $invoice = $this->db->get_where('v_invoice', ['invoice_id' => $invoice_id])->row();
- if (!$invoice) {
- return ['success' => false, 'message' => 'Invoice tidak ditemukan'];
- }
- // Cek apakah sudah ada invoice_sales_order_id
- if (!empty($invoice->invoice_sales_order_id)) {
- if (!empty($invoice->invoice_jurnal_id)) {
- return ['success' => true, 'message' => 'Invoice sudah lengkap'];
- } else {
- return $this->buat_sales_invoice($invoice, $invoice->invoice_sales_order_id);
- }
- }
- // Jika sudah ada invoice_jurnal_id (SI lama), skip
- if (!empty($invoice->invoice_jurnal_id)) {
- return [
- 'success' => true,
- 'message' => 'Invoice sudah sync sebelumnya',
- 'skip' => true
- ];
- }
- // 2. CEK/SYNC CUSTOMER
- $customer_result = $this->check_customer($invoice);
- if (!$customer_result['success']) {
- return $customer_result;
- }
- $customer_jurnal_id = $customer_result['pelanggan_jurnal_id'];
- // 3. BUAT SALES ORDER (SO) DULU
- return $this->buat_sales_order($invoice, $customer_jurnal_id);
- } catch (Exception $e) {
- return ['success' => false, 'message' => 'Error: ' . $e->getMessage()];
- }
- }
- private function buat_sales_order($invoice, $customer_jurnal_id)
- {
- try {
- // Ambil detail invoice
- $details = $this->db->order_by('invoice_detail_id', 'asc')->get_where('sid_invoice_detail', ['invoice_id' => $invoice->invoice_id])->result();
- if (empty($details)) {
- return ['success' => false, 'message' => 'Detail Invoice kosong'];
- }
- // Hitung total transaksi (nilai penuh)
- $total_transaction = 0;
- $transactionLines = [];
- foreach ($details as $detail) {
- $product_name = in_array($detail->invoice_detail_desc, ['Biaya Instalasi', 'Sewa Alat']) ? $detail->invoice_detail_desc : 'Tagihan Bulanan';
- $transactionLines[] = [
- 'product_name' => $product_name,
- 'quantity' => (int)($detail->invoice_detail_qty ?? 1),
- 'rate' => (int)($detail->invoice_detail_tarif ?? 0),
- 'discount' => (int)($detail->invoice_detail_disc ?? 0)
- ];
- }
- // Siapkan payload untuk Sales Order (SO)
- $email = strtolower(trim($invoice->pelanggan_email ?? ''));
- if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
- }
- $payload = [
- 'sales_order' => [
- 'transaction_date' => date('Y-m-d', strtotime($invoice->invoice_tanggal)),
- 'due_date' => date('Y-m-d', strtotime($invoice->invoice_tanggal_tempo)),
- 'transaction_no' => 'SO-' . $invoice->invoice_nomor,
- 'person_id' => $customer_jurnal_id,
- 'email' => $email,
- 'address' => $invoice->pelanggan_alamat ?? '',
- 'term_name' => $invoice->jenis_bayar_nama ?? 'Custom',
- 'transaction_lines_attributes' => $transactionLines,
- 'is_shipped' => false,
- 'shipping_price' => 0,
- 'discount_unit' => $invoice->invoice_diskon ?? 0,
- 'discount_type_name' => 'Value',
- 'source' => 'ISKNet.id',
- 'memo' => 'Sales Order dari ISKNet.id (Total Tagihan: ' . number_format($invoice->invoice_total, 0, ',', '.') . ')'
- ]
- ];
- // Kirim Sales Order ke Mekari
- $response = $this->mekari_jurnal->request(
- 'POST',
- '/public/jurnal/api/v1/sales_orders',
- $payload
- );
- $httpCode = $response['http_code'] ?? 0;
- if ($httpCode === 201 && isset($response['response']['sales_order']['id'])) {
- $so_jurnal_id = $response['response']['sales_order']['id'];
- $so_jurnal_no = $response['response']['sales_order']['transaction_no'];
- // Update database dengan SO ID
- $this->db->where('invoice_id', $invoice->invoice_id)->update('sid_invoice', [
- 'invoice_sales_order_id' => $so_jurnal_id,
- 'invoice_sales_order_no' => $so_jurnal_no,
- 'invoice_jurnal_response' => json_encode($response['response']['sales_order']),
- 'invoice_jurnal_sync_at' => date('Y-m-d H:i:s'),
- 'invoice_update' => date('Y-m-d H:i:s')
- ]);
- // Lanjutkan membuat Sales Invoice
- return $this->buat_sales_invoice($invoice, $customer_jurnal_id, $so_jurnal_id);
- } else {
- $error = $this->extract_error_simple($response);
- // Update dengan status failed
- $this->db->where('invoice_id', $invoice->invoice_id)->update('sid_invoice', [
- 'invoice_jurnal_status' => 'failed',
- 'invoice_jurnal_error' => $error,
- 'invoice_jurnal_response' => json_encode($response['response'] ?? []),
- 'invoice_jurnal_sync_at' => date('Y-m-d H:i:s'),
- 'invoice_update' => date('Y-m-d H:i:s')
- ]);
- return ['success' => false, 'message' => 'Gagal buat Sales Order : ' . $error];
- }
- } catch (Exception $e) {
- return ['success' => false, 'message' => 'API Error: ' . $e->getMessage()];
- }
- }
- private function buat_sales_invoice($invoice, $customer_jurnal_id, $so_jurnal_id = null)
- {
- try {
- if (!$so_jurnal_id) {
- $so_jurnal_id = $invoice->invoice_sales_order_id;
- }
- if (empty($so_jurnal_id)) {
- return ['success' => false, 'message' => 'Sales Order ID tidak ditemukan'];
- }
- // Cek apakah sudah ada invoice_jurnal_id
- if (!empty($invoice->invoice_jurnal_id)) {
- return [
- 'success' => true,
- 'message' => 'Sales Invoice Sudah Ada Sebelumnya',
- 'skip' => true
- ];
- }
- // Ambil detail invoice untuk membuat SI dengan nilai yang dibayar
- $details = $this->db->get_where('sid_invoice_detail', ['invoice_id' => $invoice->invoice_id])->result();
- if (empty($details)) {
- return ['success' => false, 'message' => 'Detail Invoice Kosong'];
- }
- $paid_amount = (int) $invoice->invoice_dibayar ?? 0;
- $transactionLines = [];
- // Untuk simplicity, kita buat satu line item dengan nilai yang dibayar
- $transactionLines[] = [
- 'product_name' => 'Pembayaran Invoice',
- 'quantity' => 1,
- 'rate' => $paid_amount,
- 'discount' => 0
- ];
- // Siapkan payload Sales Invoice
- $email = strtolower(trim($invoice->pelanggan_email ?? ''));
- if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
- }
- $payload = [
- 'sales_invoice' => [
- 'transaction_date' => date('Y-m-d', strtotime($invoice->invoice_tanggal)),
- 'due_date' => date('Y-m-d', strtotime($invoice->invoice_tanggal_tempo)),
- 'transaction_no' => $invoice->invoice_nomor,
- 'person_id' => $customer_jurnal_id,
- 'email' => $email,
- 'address' => $invoice->pelanggan_alamat ?? '',
- 'term_name' => $invoice->jenis_bayar_nama ?? 'Custom',
- 'transaction_lines_attributes' => $transactionLines,
- 'is_shipped' => false,
- 'shipping_price' => 0,
- 'discount_unit' => 0,
- 'discount_type_name' => 'value',
- 'deposit_to_name' => 'KAS KECIL KANTOR',
- 'deposit' => $paid_amount,
- 'selected_so_id' => $so_jurnal_id,
- 'source' => 'ISKNet.id',
- 'memo' => 'Sales Invoice dari ISKNet.id (Pembayaran: ' . number_format($paid_amount, 0, ',', '.') . ')'
- ]
- ];
- // Kirim Sales Invoice ke Mekari
- $response = $this->mekari_jurnal->request(
- 'POST',
- '/public/jurnal/api/v1/sales_invoices',
- $payload
- );
- $httpCode = $response['http_code'] ?? 0;
- if ($httpCode === 201 && isset($response['response']['sales_invoice']['id'])) {
- $si_jurnal_id = $response['response']['sales_invoice']['id'];
- $si_jurnal_no = $response['response']['sales_invoice']['transaction_no'];
- // Update database dengan SI ID
- $this->db->where('invoice_id', $invoice->invoice_id)->update('sid_invoice', [
- 'invoice_jurnal_id' => $si_jurnal_id,
- 'invoice_jurnal_no' => $si_jurnal_no,
- 'invoice_jurnal_status' => $response['response']['sales_invoice']['status'] ?? 'paid',
- 'invoice_jurnal_response' => json_encode($response['response']['sales_invoice']),
- 'invoice_jurnal_sync_at' => date('Y-m-d H:i:s'),
- 'invoice_update' => date('Y-m-d H:i:s')
- ]);
- return [
- 'success' => true,
- 'message' => 'Sales Order dan Sales Invoice berhasil dibuat',
- 'so_jurnal_id' => $so_jurnal_id,
- 'si_jurnal_id' => $si_jurnal_id
- ];
- } else {
- $error = $this->extract_error_simple($response);
- // Update dengan status failed
- $this->db->where('invoice_id', $invoice->invoice_id)->update('sid_invoice', [
- 'invoice_jurnal_status' => 'failed',
- 'invoice_jurnal_error' => $error,
- 'invoice_jurnal_response' => json_encode($response['response'] ?? []),
- 'invoice_jurnal_sync_at' => date('Y-m-d H:i:s'),
- 'invoice_update' => date('Y-m-d H:i:s')
- ]);
- return ['success' => false, 'message' => 'Gagal buat Sales Invoice: ' . $error];
- }
- } catch (Exception $e) {
- return ['success' => false, 'message' => 'API Error: ' . $e->getMessage()];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment