hr dan payroll
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
class Migration_Expand_company_bank_accounts extends CI_Migration
|
||||
{
|
||||
private function column($name, $definition)
|
||||
{
|
||||
if (!$this->db->field_exists($name, 'company_bank_accounts')) {
|
||||
$this->db->query("ALTER TABLE `company_bank_accounts` ADD `{$name}` {$definition}");
|
||||
}
|
||||
}
|
||||
|
||||
public function up()
|
||||
{
|
||||
if (!$this->db->table_exists('company_bank_accounts')) return;
|
||||
|
||||
$this->column('product_name', "VARCHAR(120) NULL AFTER `account_holder`");
|
||||
$this->column('account_type', "ENUM('savings','deposit') NOT NULL DEFAULT 'savings' AFTER `product_name`");
|
||||
$this->column('interest_rate', "DECIMAL(7,4) NOT NULL DEFAULT 0 AFTER `account_type`");
|
||||
$this->column('opened_at', "DATE NULL AFTER `interest_rate`");
|
||||
$this->column('maturity_date', "DATE NULL AFTER `opened_at`");
|
||||
$this->column('gl_account_id', "INT NULL AFTER `currency`");
|
||||
|
||||
if ($this->db->table_exists('cash_accounts')) {
|
||||
$this->db->query("UPDATE company_bank_accounts b
|
||||
JOIN cash_accounts ca ON ca.bank_account_no=b.account_number
|
||||
AND (ca.company_id=b.company_id OR ca.company_id IS NULL)
|
||||
JOIN accounts a ON a.id=ca.gl_account_id AND a.company_id=b.company_id
|
||||
SET b.gl_account_id=ca.gl_account_id
|
||||
WHERE b.gl_account_id IS NULL");
|
||||
}
|
||||
|
||||
if (!$this->db->query("SHOW INDEX FROM company_bank_accounts WHERE Key_name='idx_company_bank_report'")->row()) {
|
||||
$this->db->query("ALTER TABLE company_bank_accounts ADD KEY idx_company_bank_report(company_id,account_type,is_active,maturity_date)");
|
||||
}
|
||||
if (!$this->db->query("SHOW INDEX FROM company_bank_accounts WHERE Key_name='idx_company_bank_gl'")->row()) {
|
||||
$this->db->query("ALTER TABLE company_bank_accounts ADD KEY idx_company_bank_gl(company_id,gl_account_id)");
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
throw new RuntimeException('Metadata rekening perusahaan dipertahankan untuk audit dan dokumen lama.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Memulihkan skema pembayaran pembelian pada database yang metadata
|
||||
* migrasinya sudah maju, tetapi kolom biaya bank belum ikut terpasang.
|
||||
*/
|
||||
class Migration_Repair_purchase_payment_bank_charge_schema extends CI_Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (!$this->db->table_exists('supplier_payments')) {
|
||||
throw new RuntimeException('Tabel supplier_payments belum tersedia. Jalankan migrasi pembelian sebelumnya terlebih dahulu.');
|
||||
}
|
||||
|
||||
if (!$this->db->field_exists('bank_charge_amount', 'supplier_payments')) {
|
||||
$this->db->query('ALTER TABLE supplier_payments ADD bank_charge_amount DECIMAL(18,2) NOT NULL DEFAULT 0 AFTER amount');
|
||||
}
|
||||
if (!$this->db->field_exists('bank_charge_account_id', 'supplier_payments')) {
|
||||
$this->db->query('ALTER TABLE supplier_payments ADD bank_charge_account_id INT NULL AFTER bank_charge_amount');
|
||||
}
|
||||
if (!$this->db->field_exists('total_cash_out', 'supplier_payments')) {
|
||||
$this->db->query('ALTER TABLE supplier_payments ADD total_cash_out DECIMAL(18,2) NOT NULL DEFAULT 0 AFTER bank_charge_account_id');
|
||||
}
|
||||
|
||||
// Pembayaran lama tidak mempunyai biaya bank, sehingga total kas
|
||||
// keluar sama dengan nilai pokok pembayaran yang sudah tersimpan.
|
||||
$this->db->query('UPDATE supplier_payments SET bank_charge_amount=0 WHERE bank_charge_amount IS NULL');
|
||||
$this->db->query('UPDATE supplier_payments SET total_cash_out=amount+bank_charge_amount WHERE total_cash_out IS NULL OR total_cash_out=0');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
throw new RuntimeException('Kolom pembayaran pembelian dipertahankan untuk menjaga histori dan audit transaksi.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Memulihkan ENUM supplier_invoices.status pada database hasil clone yang
|
||||
* versi migrasinya sudah maju, tetapi definisi kolomnya masih versi lama.
|
||||
*/
|
||||
class Migration_Repair_supplier_invoice_status_enum extends CI_Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (!$this->db->table_exists('supplier_invoices')) {
|
||||
throw new RuntimeException('Tabel supplier_invoices belum tersedia. Jalankan migrasi pembelian sebelumnya terlebih dahulu.');
|
||||
}
|
||||
|
||||
// Gunakan ENUM transisi supaya seluruh nilai legacy tetap valid saat
|
||||
// dikonversi ke workflow supplier invoice yang berlaku sekarang.
|
||||
$this->db->query("ALTER TABLE supplier_invoices MODIFY status ENUM('draft','submitted','approved','verified','posted','partial','paid','cancelled','reversed') NOT NULL DEFAULT 'verified'");
|
||||
$this->db->query("UPDATE supplier_invoices SET status='verified' WHERE status IN('draft','submitted','approved')");
|
||||
$this->db->query("UPDATE supplier_invoices SET status=IF(COALESCE(balance,0)<=0,'paid','partial') WHERE status='posted'");
|
||||
$this->db->query("ALTER TABLE supplier_invoices MODIFY status ENUM('verified','partial','paid','cancelled','reversed') NOT NULL DEFAULT 'verified'");
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
throw new RuntimeException('Status supplier invoice dipertahankan untuk menjaga histori dan workflow pembayaran.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Memperbaiki akun sistem yang dibuat setelah fondasi multi-company sehingga
|
||||
* company_id-nya masih NULL dan ditolak saat jurnal divalidasi.
|
||||
*/
|
||||
class Migration_Repair_system_account_company_scope extends CI_Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
if (!$this->db->table_exists('companies')) return;
|
||||
|
||||
$company = $this->db->where('is_active', 1)->order_by('id')->get('companies')->row();
|
||||
if (!$company) {
|
||||
throw new RuntimeException('Perusahaan aktif tidak ditemukan untuk memperbaiki scope akun sistem.');
|
||||
}
|
||||
|
||||
$companyId = (int) $company->id;
|
||||
if ($this->db->table_exists('accounts') && $this->db->field_exists('company_id', 'accounts')) {
|
||||
$this->db->where('company_id IS NULL OR company_id=0', null, false)
|
||||
->update('accounts', array('company_id'=>$companyId));
|
||||
}
|
||||
|
||||
if ($this->db->table_exists('system_account_mappings') && $this->db->field_exists('company_id', 'system_account_mappings')) {
|
||||
$this->db->query(
|
||||
'UPDATE system_account_mappings m '
|
||||
.'JOIN accounts a ON a.id=m.account_id '
|
||||
.'SET m.company_id=COALESCE(NULLIF(a.company_id,0),?) '
|
||||
.'WHERE m.company_id IS NULL OR m.company_id=0',
|
||||
array($companyId)
|
||||
);
|
||||
}
|
||||
|
||||
$mapping = $this->db->select('m.account_id,a.tipe,a.is_active,a.allow_posting,a.company_id')
|
||||
->from('system_account_mappings m')
|
||||
->join('accounts a', 'a.id=m.account_id')
|
||||
->where(array('m.mapping_key'=>'goods_in_transit','m.is_active'=>1))
|
||||
->get()->row();
|
||||
if (!$mapping || $mapping->tipe !== 'asset' || !(int)$mapping->is_active || !(int)$mapping->allow_posting || !(int)$mapping->company_id) {
|
||||
throw new RuntimeException('Mapping Barang Dalam Perjalanan belum menunjuk akun Aktiva aktif milik perusahaan.');
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
throw new RuntimeException('Scope perusahaan pada akun sistem dipertahankan untuk integritas jurnal.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user