Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e5727cc78 | |||
| 796fa04a37 | |||
| a008204865 | |||
| 5347d89acb | |||
| 8d8a5e48d5 | |||
| 805cb44530 | |||
| b03ae67f75 | |||
|
|
b5028c06dd | ||
|
|
2c349c4f6e | ||
|
|
222a583538 | ||
|
|
689311d9cc | ||
|
|
49ab9e9e3c | ||
|
|
1f9c56d9a3 | ||
|
|
bed8e9641e | ||
|
|
506974ac17 | ||
|
|
16922658e6 | ||
|
|
0e865a780b | ||
|
|
d11ef00972 | ||
|
|
30606919f4 | ||
|
|
411d7e0219 | ||
|
|
383ebef8cd | ||
| e1feaa68a8 | |||
| 64f434cd78 | |||
|
|
61e2e4f2ec | ||
|
|
79fd2864cc | ||
|
|
344c5d42e6 | ||
|
|
f30c6dbb60 | ||
|
|
2d072fad16 | ||
|
|
aef86b7acf | ||
|
|
efdf8af569 | ||
|
|
712cbbb80b | ||
|
|
977694905c | ||
| ee3748066e | |||
| 709dfdae33 | |||
| e62ec1d994 | |||
| 34fb944e6e | |||
| 17445d9534 | |||
| 17423ac0b5 | |||
| c83c42698a | |||
| 009aff7d44 | |||
| 6dbe0e400b | |||
| 0ea56f09fa | |||
| a6412c9688 | |||
| bcb553ea56 | |||
| 2874fab71d | |||
| 752c372c2f | |||
| c125289b92 | |||
| fe5e6dd6cb | |||
| 5fd6db863a | |||
| fc9947bce4 | |||
| c296d5598b | |||
| 5bd8e038fc | |||
| 8f07a65485 | |||
| 7e88cf247b | |||
| 7af9fb2ca4 | |||
| 77fc97e964 | |||
| b7a00bc242 | |||
| 834f23f26e | |||
| dc88589c78 | |||
| 3871a680dd | |||
| 13af691645 | |||
| 775a390bcb | |||
| 9c87e9ce25 | |||
| 0d1dcb1b5e | |||
| 22719de06f |
104
README.md
104
README.md
@@ -1,2 +1,106 @@
|
|||||||
# be-accone
|
# be-accone
|
||||||
|
|
||||||
|
Backend service for Accone.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Generate Monthly Installments (Cicilan Aset)
|
||||||
|
|
||||||
|
Automatically creates `supplier_installment` rows for all eligible active contracts every month. This is designed to be executed via **CRON daily at 1:00 AM**.
|
||||||
|
|
||||||
|
> **Note:** No journal entries are created here — that happens at cashier payment time. The contract's `InstallmentPaid` field is also **not** updated here — it's updated when payment is received.
|
||||||
|
|
||||||
|
### Endpoint
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /one-api/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
||||||
|
```
|
||||||
|
|
||||||
|
### Request
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
|---------------|--------------------|
|
||||||
|
| **Method** | `POST` |
|
||||||
|
| **Content-Type** | `application/json` |
|
||||||
|
| **Body** | `{}` (optional `startDate` / `endDate`) |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s -X POST "https://accone.aplikasi.web.id/one-api/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional body parameters:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"startDate": "2026-07-01",
|
||||||
|
"endDate": "2026-07-31"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If omitted, defaults to the current month (`startDate` = first day, `endDate` = last day).
|
||||||
|
|
||||||
|
### Eligibility Logic (Steps 1–5)
|
||||||
|
|
||||||
|
A contract is eligible for installment generation only if **all** of the following conditions are met:
|
||||||
|
|
||||||
|
| Step | Condition |
|
||||||
|
|------|-----------|
|
||||||
|
| **1** | Contract is **active** (`IsActive = 'Y'`), status is **"belum lunas"**, has a positive `InstallmentPayAmount`, `InstallmentPaid < InstallmentNumber`, falls within the date range, and the scheduled day of month has been reached |
|
||||||
|
| **2** | Associated **Purchase Order** is **Approved** and **Active** |
|
||||||
|
| **3** | Associated **Receive Order** is **Confirmed** and **Active** |
|
||||||
|
| **4** | A parent **Supplier Invoice** exists with `IsInstallment = 'Y'` |
|
||||||
|
| **5** | No `supplier_installment` record already exists for the same PO in the same month |
|
||||||
|
|
||||||
|
### Step 6 — Insert
|
||||||
|
|
||||||
|
For each eligible contract, a row is inserted into `supplier_installment` with:
|
||||||
|
|
||||||
|
- `SupplierInstallmentStatus` = `"Pending"`
|
||||||
|
- `SupplierInstallmentIsLunas` = `"N"`
|
||||||
|
- `SupplierInstallmentDate` = the contract's scheduled day of month (capped to the last day of the month)
|
||||||
|
- `SupplierInstallmentDueDate` = same as InstallmentDate, can be changed at payment instrutions manu
|
||||||
|
|
||||||
|
### Response
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "OK",
|
||||||
|
"data": {
|
||||||
|
"startDate": "2026-07-01",
|
||||||
|
"endDate": "2026-07-31",
|
||||||
|
"totalEligible": 1,
|
||||||
|
"totalInserted": 1,
|
||||||
|
"created": [
|
||||||
|
{
|
||||||
|
"installmentID": 6,
|
||||||
|
"contractID": "11",
|
||||||
|
"purchaseOrderID": "20",
|
||||||
|
"parentInvoiceID": "16",
|
||||||
|
"parentInvoiceNumber": "PI-016/SDM-14/SM-1/VII/2026",
|
||||||
|
"amount": 5000000,
|
||||||
|
"installDate": "2026-07-22",
|
||||||
|
"dueDate": "2026-07-22"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `status` | `string` | `"OK"` on success |
|
||||||
|
| `data.startDate` | `string` | Start of the billing period (`YYYY-MM-DD`) |
|
||||||
|
| `data.endDate` | `string` | End of the billing period (`YYYY-MM-DD`) |
|
||||||
|
| `data.totalEligible` | `number` | Total contracts that passed eligibility |
|
||||||
|
| `data.totalInserted` | `number` | Total installments successfully created |
|
||||||
|
| `data.created` | `array` | List of generated installment records |
|
||||||
|
| `data.created[].installmentID` | `number` | ID of the created `supplier_installment` row |
|
||||||
|
| `data.created[].contractID` | `string` | Associated contract ID (`PurchaseOrderAssetContract`) |
|
||||||
|
| `data.created[].purchaseOrderID` | `string` | Associated purchase order ID |
|
||||||
|
| `data.created[].parentInvoiceID` | `string` | Source supplier invoice ID |
|
||||||
|
| `data.created[].parentInvoiceNumber` | `string` | Source supplier invoice number |
|
||||||
|
| `data.created[].amount` | `number` | Installment amount (IDR) |
|
||||||
|
| `data.created[].installDate` | `string` | Date the installment is issued |
|
||||||
|
| `data.created[].dueDate` | `string` | Payment due date (`installDate + 7 days`) |
|
||||||
|
|||||||
113
application/controllers/map/InventarisCoaMapping.http
Normal file
113
application/controllers/map/InventarisCoaMapping.http
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
@token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJNX1VzZXJJRCI6IjM4MCIsIk1fVXNlclVzZXJuYW1lIjoicmVnc2J5IiwiTV9Vc2VyR3JvdXBEYXNoYm9hcmQiOiJvbmUtdWlcL3Rlc3RcL3Z1ZXhcL2FjYy1vbmUtanVybmFsXC8iLCJNX1VzZXJEZWZhdWx0VF9TYW1wbGVTdGF0aW9uSUQiOiIwIiwiTV9TdGFmZk5hbWUiOiJTdGFmZiBSZWdpb25hbCIsImlzX2NvdXJpZXIiOiJOIiwidGltZV9hdXRvbG9nb3V0IjoiMTIwIiwiTV9Vc2VyTG9jYXRpb25JRCI6IjM3IiwiTV9Vc2VyTG9jYXRpb25GbGFnIjoiUiIsIlNfUmVnaW9uYWxOYW1lIjoiU3VyYWJheWEgUmF5YSIsIlNfUmVnaW9uYWxJRCI6IjYiLCJNX0JyYW5jaE5hbWUiOiIiLCJNX0JyYW5jaENvZGUiOiIiLCJNX0JyYW5jaElEIjoiMCIsImxvZ2luTGV2ZWwiOiJyZWdpb25hbCIsIk1fQnJhbmNoQ29tcGFueUlEIjoiMSIsIk1fQnJhbmNoQ29tcGFueU5hbWUiOiJQVCBQUkFNSVRBIiwiaXAiOiIxMzkuMTk1LjEyMi4yMzUiLCJhZ2VudCI6Ik1vemlsbGFcLzUuMCAoWDExOyBMaW51eCB4ODZfNjQ7IHJ2OjEzNy4wKSBHZWNrb1wvMjAxMDAxMDEgRmlyZWZveFwvMTM3LjAiLCJ2ZXJzaW9uIjoidjIiLCJsYXN0LWxvZ2luIjoiMjAyNS0wNi0wNCAxMzoyMDowNSIsIk1fU2F0ZWxsaXRlSUQiOjB9.hm6JtstjaQOzb7oDSXQ-oMWuX_jFQZH-HDr3r3OzPac"
|
||||||
|
|
||||||
|
@host = accone.aplikasi.web.id/one-api
|
||||||
|
|
||||||
|
###
|
||||||
|
// create inventaris coa mapping
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/createInvCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_InventarisGolID": 1,
|
||||||
|
"CoaInventarisID": 101,
|
||||||
|
"CoaHutangID": 102,
|
||||||
|
"CoaPembelianID": 103,
|
||||||
|
"CoaBebanPenyusutanID": 104,
|
||||||
|
"CoaAkumulasiPenyusutanID": 105,
|
||||||
|
"CoaLabaPelepasanID": 106,
|
||||||
|
"CoaRugiPelepasanID": 107
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// get inventaris coa mapping by ID
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/getInvCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_InventarisCoaMappingID": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// edit inventaris coa mapping
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/editInvCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_InventarisCoaMappingID": 1,
|
||||||
|
"M_InventarisGolID": 2,
|
||||||
|
"CoaInventarisID": 201,
|
||||||
|
"CoaHutangID": 202,
|
||||||
|
"CoaPembelianID": 203,
|
||||||
|
"CoaBebanPenyusutanID": 204,
|
||||||
|
"CoaAkumulasiPenyusutanID": 205,
|
||||||
|
"CoaLabaPelepasanID": 206,
|
||||||
|
"CoaRugiPelepasanID": 207
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// delete inventaris coa mapping
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/deleteInvCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_InventarisCoaMappingID": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// create inventaris item coa mapping
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/createInvItemCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_ItemID": 10,
|
||||||
|
"CoaInventarisID": 201,
|
||||||
|
"CoaHutangID": 202,
|
||||||
|
"CoaPembelianID": 203,
|
||||||
|
"CoaBebanPenyusutanID": 204,
|
||||||
|
"CoaAkumulasiPenyusutanID": 205,
|
||||||
|
"CoaLabaPelepasanID": 206,
|
||||||
|
"CoaRugiPelepasanID": 207
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// get inventaris item coa mapping by ID
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/getInvItemCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_InventarisItemCoaMappingID": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// edit inventaris item coa mapping
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/editInvItemCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_InventarisItemCoaMappingID": 1,
|
||||||
|
"M_ItemID": 11,
|
||||||
|
"CoaInventarisID": 301,
|
||||||
|
"CoaHutangID": 302,
|
||||||
|
"CoaPembelianID": 303,
|
||||||
|
"CoaBebanPenyusutanID": 304,
|
||||||
|
"CoaAkumulasiPenyusutanID": 305,
|
||||||
|
"CoaLabaPelepasanID": 306,
|
||||||
|
"CoaRugiPelepasanID": 307
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// delete inventaris item coa mapping
|
||||||
|
POST https://{{host}}/map/InventarisCoaMapping/deleteInvItemCoaMapping/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"M_InventarisItemCoaMappingID": 1
|
||||||
|
}
|
||||||
624
application/controllers/map/InventarisCoaMapping.php
Normal file
624
application/controllers/map/InventarisCoaMapping.php
Normal file
@@ -0,0 +1,624 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class InventarisCoaMapping extends MY_Controller
|
||||||
|
{
|
||||||
|
var $db;
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Inventaris COA Mapping API";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## QUERY ##
|
||||||
|
public function getListCoa()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
throw new Exception('Invalid token');
|
||||||
|
}
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
$keyword = "%" . $para['keyword'] . "%";
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
coaID,
|
||||||
|
coaAccountNo,
|
||||||
|
coaDescription
|
||||||
|
FROM coa
|
||||||
|
WHERE coaIsInput = 'Y'
|
||||||
|
AND (
|
||||||
|
coaDescription LIKE ?
|
||||||
|
OR coaAccountNo LIKE ?
|
||||||
|
)
|
||||||
|
AND coaIsActive = 'Y'
|
||||||
|
LIMIT 15";
|
||||||
|
$que = $this->db->query($sql, [$keyword, $keyword]);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception('failed to query data inventaris gol', 1);
|
||||||
|
}
|
||||||
|
$data = $que->result_array();
|
||||||
|
|
||||||
|
$this->sys_ok($data);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$msg = '[Error] ' . $e->getMessage();
|
||||||
|
$code = $e->getCode();
|
||||||
|
if ($code == 0) {
|
||||||
|
$this->sys_error($msg);
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db($msg);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getListInventarisGol()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
throw new Exception('Invalid token');
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
M_InventarisGolID,
|
||||||
|
M_InventarisGolCode,
|
||||||
|
M_InventarisGolName
|
||||||
|
FROM m_inventaris_gol gol
|
||||||
|
WHERE gol.M_InventarisGolIsActive = 'Y'
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM m_inventaris_coa_mapping m
|
||||||
|
WHERE m.M_InventarisCoaMappingM_InventarisGolID = gol.M_InventarisGolID
|
||||||
|
AND m.M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
);";
|
||||||
|
$que = $this->db->query($sql);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception('failed to query data inventaris gol', 1);
|
||||||
|
}
|
||||||
|
$data = $que->result_array();
|
||||||
|
|
||||||
|
$output = [
|
||||||
|
'records' => $data,
|
||||||
|
'total' => count($data)
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->sys_ok($output);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$msg = '[Error] ' . $e->getMessage();
|
||||||
|
$code = $e->getCode();
|
||||||
|
if ($code == 0) {
|
||||||
|
$this->sys_error($msg);
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db($msg);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getListInventorygolMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
throw new Exception('invalid token');
|
||||||
|
}
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
$keyword = "%" . $para['keyword'] . "%";
|
||||||
|
|
||||||
|
$limit = 10;
|
||||||
|
$offset = 0;
|
||||||
|
if ($para['currpage'] > 0) {
|
||||||
|
$offset = ($para['currpage'] - 1) * $limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
M_InventarisGolID,
|
||||||
|
M_InventarisGolCode,
|
||||||
|
M_InventarisGolName,
|
||||||
|
M_InventarisCoaMappingID,
|
||||||
|
M_InventarisCoaMappingCoaInventarisID,
|
||||||
|
coaInv.coaAccountNo AS CoaInventarisAccountNo,
|
||||||
|
coaInv.coaDescription AS CoaInventarisDescription,
|
||||||
|
M_InventarisCoaMappingCoaHutangID,
|
||||||
|
coaHtg.coaAccountNo AS CoaHutangAccountNo,
|
||||||
|
coaHtg.coaDescription AS CoaHutangDescription,
|
||||||
|
M_InventarisCoaMappingCoaBebanPenyusutanID,
|
||||||
|
coaBbn.coaAccountNo AS CoaBebanPenyusutanAccountNo,
|
||||||
|
coaBbn.coaDescription AS CoaBebanPenyusutanDescription,
|
||||||
|
M_InventarisCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
coaAkm.coaAccountNo AS CoaAkumulasiPenyusutanAccountNo,
|
||||||
|
coaAkm.coaDescription AS CoaAkumulasiPenyusutanDescription,
|
||||||
|
M_InventarisCoaMappingCoaLabaPelepasanID,
|
||||||
|
coaLab.coaAccountNo AS CoaLabaPelepasanAccountNo,
|
||||||
|
coaLab.coaDescription AS CoaLabaPelepasanDescription,
|
||||||
|
M_InventarisCoaMappingCoaRugiPelepasanID,
|
||||||
|
coaRug.coaAccountNo AS CoaRugiPelepasanAccountNo,
|
||||||
|
coaRug.coaDescription AS CoaRugiPelepasanDescription
|
||||||
|
FROM m_inventaris_gol
|
||||||
|
JOIN m_inventaris_coa_mapping
|
||||||
|
ON M_InventarisCoaMappingM_InventarisGolID = M_InventarisGolID
|
||||||
|
AND M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisGolIsActive = 'Y'
|
||||||
|
AND M_InventarisGolName LIKE ?
|
||||||
|
LEFT JOIN coa AS coaInv
|
||||||
|
ON M_InventarisCoaMappingCoaInventarisID = coaInv.coaID
|
||||||
|
LEFT JOIN coa AS coaHtg
|
||||||
|
ON M_InventarisCoaMappingCoaHutangID = coaHtg.coaID
|
||||||
|
LEFT JOIN coa AS coaBbn
|
||||||
|
ON M_InventarisCoaMappingCoaBebanPenyusutanID = coaBbn.coaID
|
||||||
|
LEFT JOIN coa AS coaAkm
|
||||||
|
ON M_InventarisCoaMappingCoaAkumulasiPenyusutanID = coaAkm.coaID
|
||||||
|
LEFT JOIN coa AS coaLab
|
||||||
|
ON M_InventarisCoaMappingCoaLabaPelepasanID = coaLab.coaID
|
||||||
|
LEFT JOIN coa AS coaRug
|
||||||
|
ON M_InventarisCoaMappingCoaRugiPelepasanID = coaRug.coaID
|
||||||
|
WHERE M_InventarisGolIsActive = 'Y'";
|
||||||
|
|
||||||
|
$sql_data = $sql . " ORDER BY M_InventarisGolID LIMIT ? OFFSET ? ";
|
||||||
|
$que = $this->db->query($sql_data, [
|
||||||
|
$keyword,
|
||||||
|
$limit,
|
||||||
|
$offset
|
||||||
|
]);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception('failed to query data mapping coa inventaris golongan', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql_total = "SELECT COUNT(*) AS total FROM ($sql) AS x";
|
||||||
|
$que_total = $this->db->query($sql_total, [$keyword]);
|
||||||
|
if (!$que_total) {
|
||||||
|
throw new Exception('failed to get total rows data', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sys_ok([
|
||||||
|
"records" => $que->result_array(),
|
||||||
|
"total" => $que_total->row_array()['total']
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$msg = '[Error] ' . $e->getMessage();
|
||||||
|
$code = $e->getCode();
|
||||||
|
if ($code == 0) {
|
||||||
|
$this->sys_error($msg);
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db($msg);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInvCoaMappingDetail()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
M_InventarisCoaMappingID,
|
||||||
|
M_InventarisCoaMappingM_InventarisGolID,
|
||||||
|
M_InventarisCoaMappingCoaInventarisID,
|
||||||
|
M_InventarisCoaMappingCoaHutangID,
|
||||||
|
M_InventarisCoaMappingCoaPembelianID,
|
||||||
|
M_InventarisCoaMappingCoaBebanPenyusutanID,
|
||||||
|
M_InventarisCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
M_InventarisCoaMappingCoaLabaPelepasanID,
|
||||||
|
M_InventarisCoaMappingCoaRugiPelepasanID,
|
||||||
|
M_InventarisCoaMappingCreatedUserID,
|
||||||
|
M_InventarisCoaMappingCreated,
|
||||||
|
M_InventarisCoaMappingLastUpdated
|
||||||
|
FROM m_inventaris_coa_mapping
|
||||||
|
WHERE M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [$para['M_InventarisCoaMappingID']]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->sys_error_db("[Error] get data m_inventaris_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$data = $query->row_array();
|
||||||
|
|
||||||
|
$this->sys_ok($data);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## MUTATIONS ##
|
||||||
|
public function createInvCoaMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
$user = $this->sys_user;
|
||||||
|
|
||||||
|
$sql = "INSERT INTO m_inventaris_coa_mapping (
|
||||||
|
M_InventarisCoaMappingM_InventarisGolID,
|
||||||
|
M_InventarisCoaMappingCoaInventarisID,
|
||||||
|
M_InventarisCoaMappingCoaHutangID,
|
||||||
|
M_InventarisCoaMappingCoaPembelianID,
|
||||||
|
M_InventarisCoaMappingCoaBebanPenyusutanID,
|
||||||
|
M_InventarisCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
M_InventarisCoaMappingCoaLabaPelepasanID,
|
||||||
|
M_InventarisCoaMappingCoaRugiPelepasanID,
|
||||||
|
M_InventarisCoaMappingCreatedUserID,
|
||||||
|
M_InventarisCoaMappingCreated,
|
||||||
|
M_InventarisCoaMappingLastUpdated
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,NOW(),NOW())";
|
||||||
|
$query = $this->db->query($sql, [
|
||||||
|
$para['M_InventarisGolID'],
|
||||||
|
$para['CoaInventarisID'],
|
||||||
|
$para['CoaHutangID'],
|
||||||
|
$para['CoaPembelianID'],
|
||||||
|
$para['CoaBebanPenyusutanID'],
|
||||||
|
$para['CoaAkumulasiPenyusutanID'],
|
||||||
|
$para['CoaLabaPelepasanID'],
|
||||||
|
$para['CoaRugiPelepasanID'],
|
||||||
|
$user['M_UserID']
|
||||||
|
]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] insert into table m_inventaris_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$insertID = $this->db->insert_id();
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
$this->sys_ok($insertID);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editInvCoaMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
$user = $this->sys_user;
|
||||||
|
|
||||||
|
$sql = "UPDATE m_inventaris_coa_mapping SET
|
||||||
|
M_InventarisCoaMappingM_InventarisGolID = ?,
|
||||||
|
M_InventarisCoaMappingCoaInventarisID = ?,
|
||||||
|
M_InventarisCoaMappingCoaHutangID = ?,
|
||||||
|
M_InventarisCoaMappingCoaPembelianID = ?,
|
||||||
|
M_InventarisCoaMappingCoaBebanPenyusutanID = ?,
|
||||||
|
M_InventarisCoaMappingCoaAkumulasiPenyusutanID = ?,
|
||||||
|
M_InventarisCoaMappingCoaLabaPelepasanID = ?,
|
||||||
|
M_InventarisCoaMappingCoaRugiPelepasanID = ?,
|
||||||
|
M_InventarisCoaMappingLastUpdated = NOW()
|
||||||
|
WHERE M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [
|
||||||
|
$para['M_InventarisGolID'],
|
||||||
|
$para['CoaInventarisID'],
|
||||||
|
$para['CoaHutangID'],
|
||||||
|
$para['CoaPembelianID'],
|
||||||
|
$para['CoaBebanPenyusutanID'],
|
||||||
|
$para['CoaAkumulasiPenyusutanID'],
|
||||||
|
$para['CoaLabaPelepasanID'],
|
||||||
|
$para['CoaRugiPelepasanID'],
|
||||||
|
$para['M_InventarisCoaMappingID']
|
||||||
|
]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] update table m_inventaris_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
$this->sys_ok("[Success] update data inventaris coa mapping");
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteInvCoaMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$sql = "UPDATE m_inventaris_coa_mapping SET
|
||||||
|
M_InventarisCoaMappingIsActive = 'N',
|
||||||
|
M_InventarisCoaMappingLastUpdated = NOW()
|
||||||
|
WHERE M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [$para['M_InventarisCoaMappingID']]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] soft delete data m_inventaris_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
$this->sys_ok("[Success] delete data inventaris coa mapping");
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## QUERY ITEM ##
|
||||||
|
public function getListItemInventaris()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
throw new Exception('Invalid token');
|
||||||
|
}
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
M_ItemID,
|
||||||
|
M_ItemCode,
|
||||||
|
M_ItemDesc,
|
||||||
|
M_ItemM_InventarisGolID AS itemGolID,
|
||||||
|
IFNULL(M_InventarisItemCoaMappingID, 0) AS itemCoaMapID,
|
||||||
|
M_InventarisItemCoaMappingCoaInventarisID,
|
||||||
|
coaInv.coaAccountNo AS CoaInventarisAccountNo,
|
||||||
|
coaInv.coaDescription AS CoaInventarisDescription,
|
||||||
|
M_InventarisItemCoaMappingCoaHutangID,
|
||||||
|
coaHtg.coaAccountNo AS CoaHutangAccountNo,
|
||||||
|
coaHtg.coaDescription AS CoaHutangDescription,
|
||||||
|
M_InventarisItemCoaMappingCoaBebanPenyusutanID,
|
||||||
|
coaBbn.coaAccountNo AS CoaBebanPenyusutanAccountNo,
|
||||||
|
coaBbn.coaDescription AS CoaBebanPenyusutanDescription,
|
||||||
|
M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
coaAkm.coaAccountNo AS CoaAkumulasiPenyusutanAccountNo,
|
||||||
|
coaAkm.coaDescription AS CoaAkumulasiPenyusutanDescription,
|
||||||
|
M_InventarisItemCoaMappingCoaLabaPelepasanID,
|
||||||
|
coaLab.coaAccountNo AS CoaLabaPelepasanAccountNo,
|
||||||
|
coaLab.coaDescription AS CoaLabaPelepasanDescription,
|
||||||
|
M_InventarisItemCoaMappingCoaRugiPelepasanID,
|
||||||
|
coaRug.coaAccountNo AS CoaRugiPelepasanAccountNo,
|
||||||
|
coaRug.coaDescription AS CoaRugiPelepasanDescription
|
||||||
|
FROM m_item
|
||||||
|
LEFT JOIN m_inventaris_item_coa_mapping
|
||||||
|
ON M_ItemID = M_InventarisItemCoaMappingM_ItemID
|
||||||
|
AND M_InventarisItemCoaMappingIsActive = 'Y'
|
||||||
|
LEFT JOIN coa AS coaInv
|
||||||
|
ON M_InventarisItemCoaMappingCoaInventarisID = coaInv.coaID
|
||||||
|
LEFT JOIN coa AS coaHtg
|
||||||
|
ON M_InventarisItemCoaMappingCoaHutangID = coaHtg.coaID
|
||||||
|
LEFT JOIN coa AS coaBbn
|
||||||
|
ON M_InventarisItemCoaMappingCoaBebanPenyusutanID = coaBbn.coaID
|
||||||
|
LEFT JOIN coa AS coaAkm
|
||||||
|
ON M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID = coaAkm.coaID
|
||||||
|
LEFT JOIN coa AS coaLab
|
||||||
|
ON M_InventarisItemCoaMappingCoaLabaPelepasanID = coaLab.coaID
|
||||||
|
LEFT JOIN coa AS coaRug
|
||||||
|
ON M_InventarisItemCoaMappingCoaRugiPelepasanID = coaRug.coaID
|
||||||
|
WHERE M_ItemItem_CategoryID = 2
|
||||||
|
AND M_ItemM_InventarisGolID = ?
|
||||||
|
AND M_ItemIsActive = 'Y'";
|
||||||
|
$que = $this->db->query($sql, [
|
||||||
|
$para['golID']
|
||||||
|
]);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception('failed to query data inventaris gol', 1);
|
||||||
|
}
|
||||||
|
$data = $que->result_array();
|
||||||
|
|
||||||
|
$output = [
|
||||||
|
'records' => $data,
|
||||||
|
'total' => count($data)
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->sys_ok($output);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$msg = '[Error] ' . $e->getMessage();
|
||||||
|
$code = $e->getCode();
|
||||||
|
if ($code == 0) {
|
||||||
|
$this->sys_error($msg);
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db($msg);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInvItemCoaMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
M_InventarisItemCoaMappingID,
|
||||||
|
M_InventarisItemCoaMappingM_ItemID,
|
||||||
|
M_InventarisItemCoaMappingCoaInventarisID,
|
||||||
|
M_InventarisItemCoaMappingCoaHutangID,
|
||||||
|
M_InventarisItemCoaMappingCoaPembelianID,
|
||||||
|
M_InventarisItemCoaMappingCoaBebanPenyusutanID,
|
||||||
|
M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
M_InventarisItemCoaMappingCoaLabaPelepasanID,
|
||||||
|
M_InventarisItemCoaMappingCoaRugiPelepasanID,
|
||||||
|
M_InventarisItemCoaMappingCreatedUserID,
|
||||||
|
M_InventarisItemCoaMappingCreated,
|
||||||
|
M_InventarisItemCoaMappingLastUpdated
|
||||||
|
FROM m_inventaris_item_coa_mapping
|
||||||
|
WHERE M_InventarisItemCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisItemCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [$para['M_InventarisItemCoaMappingID']]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->sys_error_db("[Error] get data m_inventaris_item_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$data = $query->row_array();
|
||||||
|
|
||||||
|
$this->sys_ok($data);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## MUTATIONS ITEM ##
|
||||||
|
public function createInvItemCoaMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
$user = $this->sys_user;
|
||||||
|
|
||||||
|
$sql = "INSERT INTO m_inventaris_item_coa_mapping (
|
||||||
|
M_InventarisItemCoaMappingM_ItemID,
|
||||||
|
M_InventarisItemCoaMappingCoaInventarisID,
|
||||||
|
M_InventarisItemCoaMappingCoaHutangID,
|
||||||
|
M_InventarisItemCoaMappingCoaPembelianID,
|
||||||
|
M_InventarisItemCoaMappingCoaBebanPenyusutanID,
|
||||||
|
M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID,
|
||||||
|
M_InventarisItemCoaMappingCoaLabaPelepasanID,
|
||||||
|
M_InventarisItemCoaMappingCoaRugiPelepasanID,
|
||||||
|
M_InventarisItemCoaMappingCreatedUserID,
|
||||||
|
M_InventarisItemCoaMappingCreated,
|
||||||
|
M_InventarisItemCoaMappingLastUpdated
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,NOW(),NOW())";
|
||||||
|
$query = $this->db->query($sql, [
|
||||||
|
$para['M_ItemID'],
|
||||||
|
$para['CoaInventarisID'],
|
||||||
|
$para['CoaHutangID'],
|
||||||
|
$para['CoaPembelianID'],
|
||||||
|
$para['CoaBebanPenyusutanID'],
|
||||||
|
$para['CoaAkumulasiPenyusutanID'],
|
||||||
|
$para['CoaLabaPelepasanID'],
|
||||||
|
$para['CoaRugiPelepasanID'],
|
||||||
|
$user['M_UserID']
|
||||||
|
]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] insert into table m_inventaris_item_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$insertID = $this->db->insert_id();
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
$this->sys_ok("[Success] insert coa item");
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editInvItemCoaMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
$user = $this->sys_user;
|
||||||
|
|
||||||
|
$sql = "UPDATE m_inventaris_item_coa_mapping SET
|
||||||
|
M_InventarisItemCoaMappingM_ItemID = ?,
|
||||||
|
M_InventarisItemCoaMappingCoaInventarisID = ?,
|
||||||
|
M_InventarisItemCoaMappingCoaHutangID = ?,
|
||||||
|
M_InventarisItemCoaMappingCoaPembelianID = ?,
|
||||||
|
M_InventarisItemCoaMappingCoaBebanPenyusutanID = ?,
|
||||||
|
M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID = ?,
|
||||||
|
M_InventarisItemCoaMappingCoaLabaPelepasanID = ?,
|
||||||
|
M_InventarisItemCoaMappingCoaRugiPelepasanID = ?,
|
||||||
|
M_InventarisItemCoaMappingLastUpdated = NOW()
|
||||||
|
WHERE M_InventarisItemCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisItemCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [
|
||||||
|
$para['M_ItemID'],
|
||||||
|
$para['CoaInventarisID'],
|
||||||
|
$para['CoaHutangID'],
|
||||||
|
$para['CoaPembelianID'],
|
||||||
|
$para['CoaBebanPenyusutanID'],
|
||||||
|
$para['CoaAkumulasiPenyusutanID'],
|
||||||
|
$para['CoaLabaPelepasanID'],
|
||||||
|
$para['CoaRugiPelepasanID'],
|
||||||
|
$para['M_InventarisItemCoaMappingID']
|
||||||
|
]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] update table m_inventaris_item_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
$this->sys_ok("[Success] update data inventaris item coa mapping");
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteInvItemCoaMapping()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->isLogin) {
|
||||||
|
$this->sys_error("invalid token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$sql = "UPDATE m_inventaris_item_coa_mapping SET
|
||||||
|
M_InventarisItemCoaMappingIsActive = 'N',
|
||||||
|
M_InventarisItemCoaMappingLastUpdated = NOW()
|
||||||
|
WHERE M_InventarisItemCoaMappingIsActive = 'Y'
|
||||||
|
AND M_InventarisItemCoaMappingID = ?";
|
||||||
|
$query = $this->db->query($sql, [$para['M_InventarisItemCoaMappingID']]);
|
||||||
|
if (!$query) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] soft delete data m_inventaris_item_coa_mapping");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
$this->sys_ok("[Success] delete data inventaris item coa mapping");
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$msg = $exc->getMessage();
|
||||||
|
$this->sys_error($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -496,6 +496,7 @@ class Fakturv4 extends MY_Controller
|
|||||||
ELSE ''
|
ELSE ''
|
||||||
END as WarehouseName,
|
END as WarehouseName,
|
||||||
ReceiveOrderPoID,
|
ReceiveOrderPoID,
|
||||||
|
ReceiveOrderPoTypePurchase,
|
||||||
PurchaseOrderItemCategoryID
|
PurchaseOrderItemCategoryID
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN supplier_invoice_detail ON SupplierInvoiceID = SupplierInvoiceDetailSupplierInvoiceID
|
JOIN supplier_invoice_detail ON SupplierInvoiceID = SupplierInvoiceDetailSupplierInvoiceID
|
||||||
@@ -588,12 +589,11 @@ class Fakturv4 extends MY_Controller
|
|||||||
'P'
|
'P'
|
||||||
) AS DiscountType,
|
) AS DiscountType,
|
||||||
SupplierInvoiceReceiveOrderPoID,
|
SupplierInvoiceReceiveOrderPoID,
|
||||||
ReceiveOrderPoNumber
|
ReceiveOrderPoNumber,
|
||||||
|
ReceiveOrderPoTypePurchase AS typePurchase
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
||||||
-- JOIN purchase_order ON SupplierInvoicePurchaseOrderID = PurchaseOrderID
|
|
||||||
-- AND PurchaseOrderIsActive = 'Y'
|
|
||||||
WHERE SupplierInvoiceIsActive = 'Y'
|
WHERE SupplierInvoiceIsActive = 'Y'
|
||||||
AND SupplierInvoiceID = ?";
|
AND SupplierInvoiceID = ?";
|
||||||
$que = $this->db->query($sql, $para['SInvoiceID']);
|
$que = $this->db->query($sql, $para['SInvoiceID']);
|
||||||
@@ -601,6 +601,7 @@ class Fakturv4 extends MY_Controller
|
|||||||
$this->sys_error_db('[Error] get detail data invoice');
|
$this->sys_error_db('[Error] get detail data invoice');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
$data = $que->row_array();
|
||||||
|
|
||||||
$sqldet = "SELECT
|
$sqldet = "SELECT
|
||||||
SupplierInvoiceDetailID,
|
SupplierInvoiceDetailID,
|
||||||
@@ -636,7 +637,30 @@ class Fakturv4 extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $que->result_array()[0];
|
if (isset($data['typePurchase']) && $data['typePurchase'] == 'aset') {
|
||||||
|
$sql_dp = "SELECT
|
||||||
|
IFNULL(SupplierDownpaymentAmount, 0) AS dp_amount
|
||||||
|
FROM supplier_invoice
|
||||||
|
JOIN receive_order_po
|
||||||
|
ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
||||||
|
JOIN purchase_order_asset_contract
|
||||||
|
ON PurchaseOrderAssetContractReceiveOrderPoID = ReceiveOrderPoID
|
||||||
|
AND PurchaseOrderAssetContractIsActive = 'Y'
|
||||||
|
JOIN supplier_downpayment
|
||||||
|
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderAssetContractPurchaseOrderID
|
||||||
|
AND SupplierDownpaymentIsActive = 'Y'
|
||||||
|
WHERE SupplierInvoiceID = ?";
|
||||||
|
$que_dp = $this->db->query($sql_dp, [
|
||||||
|
$para['SInvoiceID']
|
||||||
|
]);
|
||||||
|
if (!$que_dp) {
|
||||||
|
$this->sys_error_db("[Error] get info contract asset");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$dp_amount = $que_dp->row_array()['dp_amount'];
|
||||||
|
$data['dp_amount'] = $dp_amount;
|
||||||
|
}
|
||||||
|
|
||||||
$data['detail'] = $quedet->result_array();
|
$data['detail'] = $quedet->result_array();
|
||||||
|
|
||||||
$result = $data;
|
$result = $data;
|
||||||
@@ -1317,7 +1341,8 @@ class Fakturv4 extends MY_Controller
|
|||||||
supplier_invoice_detail.*,
|
supplier_invoice_detail.*,
|
||||||
ReceiveOrderPoNumber,
|
ReceiveOrderPoNumber,
|
||||||
ReceiveOrderPoM_BranchCode,
|
ReceiveOrderPoM_BranchCode,
|
||||||
ReceiveOrderPoS_RegionalID
|
ReceiveOrderPoS_RegionalID,
|
||||||
|
ReceiveOrderPoTypePurchase AS typePurchase
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN supplier_invoice_detail ON SupplierInvoiceDetailSupplierInvoiceID = SupplierInvoiceID
|
JOIN supplier_invoice_detail ON SupplierInvoiceDetailSupplierInvoiceID = SupplierInvoiceID
|
||||||
AND SupplierInvoiceDetailIsActive = 'Y'
|
AND SupplierInvoiceDetailIsActive = 'Y'
|
||||||
@@ -1453,7 +1478,6 @@ class Fakturv4 extends MY_Controller
|
|||||||
$coapph = $quepph->result_array()[0];
|
$coapph = $quepph->result_array()[0];
|
||||||
|
|
||||||
$pphval = doubleval($invoice[0]['SupplierInvoiceTaxAmountPph']);
|
$pphval = doubleval($invoice[0]['SupplierInvoiceTaxAmountPph']);
|
||||||
|
|
||||||
if ($pphval > 0.00) {
|
if ($pphval > 0.00) {
|
||||||
$insertpph = $this->InsertJurnalTx(
|
$insertpph = $this->InsertJurnalTx(
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
@@ -1465,22 +1489,22 @@ class Fakturv4 extends MY_Controller
|
|||||||
);
|
);
|
||||||
if (!$insertpph['status']) {
|
if (!$insertpph['status']) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db($insertpajak['msg']);
|
$this->sys_error_db($insertpph['msg']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# insert shipping cost ke jurnal #
|
# insert shipping cost ke jurnal #
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
$queryshipcost = $this->db->query($sqlcoa, ['5320700001']);
|
|
||||||
if (!$queryshipcost) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] get coa cost ");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$coashipcost = $queryshipcost->result_array()[0];
|
|
||||||
|
|
||||||
if ($ship_cost > 0.00) {
|
if ($ship_cost > 0.00) {
|
||||||
|
$queryshipcost = $this->db->query($sqlcoa, ['5320700001']);
|
||||||
|
if (!$queryshipcost) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] get coa cost ");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$coashipcost = $queryshipcost->result_array()[0];
|
||||||
|
|
||||||
$insertcost = $this->InsertJurnalTx(
|
$insertcost = $this->InsertJurnalTx(
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
$coashipcost['coaID'],
|
$coashipcost['coaID'],
|
||||||
@@ -1496,6 +1520,63 @@ class Fakturv4 extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Insert jurnal tx for down payment asset */
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
if (isset($invoice[0]['typePurchase']) && $invoice[0]['typePurchase'] == 'aset') {
|
||||||
|
$sql_dpasset = "SELECT
|
||||||
|
PurchaseOrderAssetContractID,
|
||||||
|
PurchaseOrderAssetContractName,
|
||||||
|
SupplierDownpaymentAmount,
|
||||||
|
coaID,
|
||||||
|
coaDescription
|
||||||
|
FROM purchase_order_asset_contract
|
||||||
|
JOIN purchase_order ON PurchaseOrderID = PurchaseOrderAssetContractPurchaseOrderID
|
||||||
|
JOIN supplier_downpayment
|
||||||
|
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
|
||||||
|
AND SupplierDownpaymentIsActive = 'Y'
|
||||||
|
JOIN purchase_order_detail
|
||||||
|
ON PurchaseOrderID = PurchaseOrderDetailPurchaseOrderID
|
||||||
|
AND PurchaseOrderDetailIsActive = 'Y'
|
||||||
|
JOIN m_item ON M_ItemID = PurchaseOrderDetailItemID
|
||||||
|
AND M_ItemItem_CategoryID = 3
|
||||||
|
JOIN fa_class ON Fa_ClassID = M_ItemFa_ClassID
|
||||||
|
AND Fa_ClassIsActive = 'Y'
|
||||||
|
JOIN coa ON coaID = Fa_ClassDownPaymentCoaID
|
||||||
|
AND coaIsActive = 'Y'
|
||||||
|
WHERE PurchaseOrderAssetContractReceiveOrderPoID = ?
|
||||||
|
AND PurchaseOrderAssetContractIsActive = 'Y'
|
||||||
|
LIMIT 1";
|
||||||
|
$que_dpasset = $this->db->query($sql_dpasset, [
|
||||||
|
$invoice[0]['SupplierInvoiceReceiveOrderPoID']
|
||||||
|
]);
|
||||||
|
if (!$que_dpasset) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] query dp asset not error");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$dpasset_coa = $que_dpasset->row_array();
|
||||||
|
if (!empty($dpasset_coa)) {
|
||||||
|
$totalDP = round($dpasset_coa['SupplierDownpaymentAmount'], 2);
|
||||||
|
if ($totalDP > 0) {
|
||||||
|
$insert_dp = $this->InsertJurnalTx(
|
||||||
|
$jurnalID,
|
||||||
|
$dpasset_coa['coaID'],
|
||||||
|
$dpasset_coa['coaDescription'],
|
||||||
|
$user['M_UserID'],
|
||||||
|
0,
|
||||||
|
$totalDP
|
||||||
|
);
|
||||||
|
if (!$insert_dp['status']) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db($insert_dp['msg']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$invoice = $this->CalcProrateDownPaymentAsset($invoice, $totalDP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// insert jurnal tx hutang per item (kredit)
|
// insert jurnal tx hutang per item (kredit)
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
foreach ($invoice as $key => $inv) {
|
foreach ($invoice as $key => $inv) {
|
||||||
@@ -1554,101 +1635,26 @@ class Fakturv4 extends MY_Controller
|
|||||||
0,
|
0,
|
||||||
$kredit
|
$kredit
|
||||||
);
|
);
|
||||||
if (!$status) {
|
if (!$status['status']) {
|
||||||
$this->sys_error_db($status['msg']);
|
$this->sys_error_db($status['msg']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
} else if ($item['M_ItemItem_CategoryID'] == '2') {
|
} else if ($item['M_ItemItem_CategoryID'] == '2') {
|
||||||
if (empty($item['M_ItemM_InventarisGolID'])) {
|
$this->InsertJurnalTxInventaris($jurnalID, $item, $inv, $user['M_UserID']);
|
||||||
$this->db->trans_rollback();
|
} else if ($item['M_ItemItem_CategoryID'] == '3') {
|
||||||
$this->sys_error_db("[Error] item golongan inventaris belum ditentukan");
|
$this->InsertJurnalTxAsset($jurnalID, $item['M_ItemID'], $inv, $user['M_UserID']);
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql_coainv = "SELECT
|
|
||||||
CoaMapInventarisHutangCoaID,
|
|
||||||
CoaMapInventarisHutangCoaNo,
|
|
||||||
CoaMapInventarisHutangCoaDesc
|
|
||||||
FROM coa_map_inventaris
|
|
||||||
WHERE CoaMapInventarisM_InventarisGolID = ?
|
|
||||||
AND CoaMapInventarisIsActive = 'Y'";
|
|
||||||
$que_coainv = $this->db->query($sql_coainv, [$item['M_ItemM_InventarisGolID']]);
|
|
||||||
if (!$que_coainv) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] failed to get coa inventaris gol");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$item_coainv = $que_coainv->row_array();
|
|
||||||
if (empty($item_coainv)) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] item inventaris coa not found");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$price = (doubleval($inv['SupplierInvoiceDetailTotal']) - doubleval($inv['SupplierInvoiceDetailDiscountPoProrata']));
|
|
||||||
// $taxPPH = doubleval($inv['SupplierInvoiceTaxPercentPph']) * $price / 100;
|
|
||||||
$taxPPN = doubleval($inv['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
|
||||||
|
|
||||||
$kredit = round($price + $taxPPN, 2);
|
|
||||||
|
|
||||||
$status = $this->InsertJurnalTx(
|
|
||||||
$jurnalID,
|
|
||||||
$item_coainv['CoaMapInventarisHutangCoaID'],
|
|
||||||
$item_coainv['CoaMapInventarisHutangCoaDesc'],
|
|
||||||
$user['M_UserID'],
|
|
||||||
0,
|
|
||||||
$kredit
|
|
||||||
);
|
|
||||||
if (!$status) {
|
|
||||||
$this->sys_error_db($status['msg']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
} else if ($item['M_ItemItem_CategoryID'] == '3' && !empty($item['M_ItemFa_ClassID'])) {
|
|
||||||
$sqlsgp = "SELECT * FROM fa_class WHERE Fa_ClassID = ? AND Fa_ClassIsActive = 'Y'";
|
|
||||||
$quesgp = $this->db->query($sqlsgp, [$item['M_ItemFa_ClassID']]);
|
|
||||||
if (!$quesgp) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] get map_nat_subgroup");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
$itemGroup = $quesgp->row_array();
|
|
||||||
|
|
||||||
if (empty($itemGroup)) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] fa class item tidak ditemukan / belum dimapping");
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$price = (doubleval($inv['SupplierInvoiceDetailTotal']) - doubleval($inv['SupplierInvoiceDetailDiscountPoProrata']));
|
|
||||||
// $taxPPH = doubleval($inv['SupplierInvoiceTaxPercentPph']) * $price / 100;
|
|
||||||
$taxPPN = doubleval($inv['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
|
||||||
|
|
||||||
$kredit = round($price + $taxPPN, 2);
|
|
||||||
|
|
||||||
$status = $this->InsertJurnalTx(
|
|
||||||
$jurnalID,
|
|
||||||
$itemGroup['Fa_ClassCoaID'],
|
|
||||||
$itemGroup['Fa_ClassCoaDesc'],
|
|
||||||
$user['M_UserID'],
|
|
||||||
0,
|
|
||||||
$kredit
|
|
||||||
);
|
|
||||||
if (!$status) {
|
|
||||||
$this->sys_error_db($status['msg']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
} else if ($item['M_ItemItem_CategoryID'] == '4') {
|
} else if ($item['M_ItemItem_CategoryID'] == '4') {
|
||||||
$this->InsertJurnalTxJasa($jurnalID, $item['M_ItemID'], $inv, $user['M_UserID']);
|
$this->InsertJurnalTxJasa($jurnalID, $item['M_ItemID'], $inv, $user['M_UserID']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sqlinvgr = "INSERT INTO jurnal_addon (
|
$sqlinvgr = "INSERT INTO jurnal_addon (
|
||||||
jurnalAddOnJurnalID,
|
jurnalAddOnJurnalID,
|
||||||
jurnalAddOnCode,
|
jurnalAddOnCode,
|
||||||
jurnalAddOnValue,
|
jurnalAddOnValue,
|
||||||
jurnalAddOnCreated,
|
jurnalAddOnCreated,
|
||||||
jurnalAddOnCreatedUserID
|
jurnalAddOnCreatedUserID
|
||||||
) VALUES (?,?,?,NOW(),?)";
|
) VALUES (?,?,?,NOW(),?)";
|
||||||
$queinvgr = $this->db->query($sqlinvgr, [
|
$queinvgr = $this->db->query($sqlinvgr, [
|
||||||
$jurnalID,
|
$jurnalID,
|
||||||
'INVGR',
|
'INVGR',
|
||||||
@@ -1671,16 +1677,81 @@ class Fakturv4 extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function InsertJurnalTxInventaris($jurnalID, $items, $invoice, $userid)
|
||||||
|
{
|
||||||
|
if (empty($items['M_ItemM_InventarisGolID'])) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] item golongan inventaris belum ditentukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql_coa = "SELECT
|
||||||
|
COALESCE(
|
||||||
|
i.M_InventarisItemCoaMappingID,
|
||||||
|
g.M_InventarisCoaMappingID
|
||||||
|
) AS MappingID,
|
||||||
|
COALESCE(
|
||||||
|
i.M_InventarisItemCoaMappingCoaHutangID,
|
||||||
|
g.M_InventarisCoaMappingCoaHutangID
|
||||||
|
) AS CoaHutangID,
|
||||||
|
c.coaDescription AS CoaHutangDesc
|
||||||
|
FROM (SELECT 1) AS inventory
|
||||||
|
LEFT JOIN m_inventaris_item_coa_mapping i
|
||||||
|
ON i.M_InventarisItemCoaMappingM_ItemID = ?
|
||||||
|
AND i.M_InventarisItemCoaMappingIsActive = 'Y'
|
||||||
|
LEFT JOIN m_inventaris_coa_mapping g
|
||||||
|
ON g.M_InventarisCoaMappingM_InventarisGolID = ?
|
||||||
|
AND g.M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
LEFT JOIN coa c
|
||||||
|
ON c.coaID = COALESCE(i.M_InventarisItemCoaMappingCoaHutangID, g.M_InventarisCoaMappingCoaHutangID)
|
||||||
|
AND c.coaIsActive = 'Y'";
|
||||||
|
$que_coa = $this->db->query($sql_coa, [
|
||||||
|
$items['M_ItemID'],
|
||||||
|
$items['M_ItemM_InventarisGolID'],
|
||||||
|
]);
|
||||||
|
if (!$que_coa) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] failed query coa hutang inventaris");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$item_coainv = $que_coa->row_array();
|
||||||
|
if (empty($item_coainv['CoaHutangID'])) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] coa ivnentory item {$items['M_ItemDesc']} not found");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$invtotal = doubleval($invoice['SupplierInvoiceDetailTotal']);
|
||||||
|
$disprorata = doubleval($invoice['SupplierInvoiceDetailDiscountPoProrata']);
|
||||||
|
$price = $invtotal - $disprorata;
|
||||||
|
$taxPPN = doubleval($invoice['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
||||||
|
$kredit = round($price + $taxPPN, 2);
|
||||||
|
|
||||||
|
$insert = $this->InsertJurnalTx(
|
||||||
|
$jurnalID,
|
||||||
|
$item_coainv['CoaHutangID'],
|
||||||
|
$item_coainv['CoaHutangDesc'],
|
||||||
|
$userid,
|
||||||
|
0,
|
||||||
|
$kredit
|
||||||
|
);
|
||||||
|
if (!$insert['status']) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db($insert['msg']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function InsertJurnalTxJasa($jurnalID, $itemid, $invoice, $userid)
|
private function InsertJurnalTxJasa($jurnalID, $itemid, $invoice, $userid)
|
||||||
{
|
{
|
||||||
$sql_coa = "SELECT
|
$sql_coa = "SELECT
|
||||||
JasaCoaMapHutangCoaID,
|
JasaCoaMapHutangCoaID,
|
||||||
JasaCoaMapHutangCoaNo,
|
JasaCoaMapHutangCoaNo,
|
||||||
JasaCoaMapHutangCoaDesc
|
JasaCoaMapHutangCoaDesc
|
||||||
FROM jasa_coa_map
|
FROM jasa_coa_map
|
||||||
JOIN coa ON coaID = JasaCoaMapHutangCoaID
|
JOIN coa ON coaID = JasaCoaMapHutangCoaID
|
||||||
AND coaIsActive = 'Y'
|
AND coaIsActive = 'Y'
|
||||||
WHERE JasaCoaMapM_ItemID = ?";
|
WHERE JasaCoaMapM_ItemID = ?";
|
||||||
$que_coa = $this->db->query($sql_coa, [$itemid]);
|
$que_coa = $this->db->query($sql_coa, [$itemid]);
|
||||||
if (!$que_coa) {
|
if (!$que_coa) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1710,13 +1781,100 @@ class Fakturv4 extends MY_Controller
|
|||||||
0,
|
0,
|
||||||
$kredit
|
$kredit
|
||||||
);
|
);
|
||||||
if (!$insert) {
|
if (!$insert['status']) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db($insert['msg']);
|
$this->sys_error_db($insert['msg']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function InsertJurnalTxAsset($jurnalID, $itemid, $invoice, $userid)
|
||||||
|
{
|
||||||
|
$sql_coa = "SELECT
|
||||||
|
Fa_ClassHutangCoaID,
|
||||||
|
Fa_ClassHutangCoaAccountNo,
|
||||||
|
Fa_ClassHutangCoaDesc
|
||||||
|
FROM m_item
|
||||||
|
JOIN fa_class ON Fa_ClassID = M_ItemFa_ClassID
|
||||||
|
WHERE M_ItemID = ?";
|
||||||
|
$que_coa = $this->db->query($sql_coa, $itemid);
|
||||||
|
if (!$que_coa) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] failed get coa hutang asset");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$coaasset = $que_coa->row_array();
|
||||||
|
if ($que_coa->num_rows() <= 0) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] aset debt coa not found");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$invtotal = doubleval($invoice['SupplierInvoiceDetailTotal']);
|
||||||
|
$disprorata = doubleval($invoice['SupplierInvoiceDetailDiscountPoProrata']);
|
||||||
|
|
||||||
|
$price = $invtotal - $disprorata;
|
||||||
|
$taxPPN = doubleval($invoice['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
||||||
|
$kredit = round($price + $taxPPN, 2);
|
||||||
|
$finalValue = round($kredit - doubleval($invoice['dpReduction']), 2);
|
||||||
|
|
||||||
|
$insert = $this->InsertJurnalTx(
|
||||||
|
$jurnalID,
|
||||||
|
$coaasset['Fa_ClassHutangCoaID'],
|
||||||
|
$coaasset['Fa_ClassHutangCoaDesc'],
|
||||||
|
$userid,
|
||||||
|
0,
|
||||||
|
$finalValue
|
||||||
|
);
|
||||||
|
if (!$insert['status']) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db($insert['msg']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function CalcProrateDownPaymentAsset($items, $dpAmount)
|
||||||
|
{
|
||||||
|
$totalKredit = 0;
|
||||||
|
foreach ($items as $key => $value) {
|
||||||
|
$invtotal = doubleval($value['SupplierInvoiceDetailTotal']);
|
||||||
|
$disprorata = doubleval($value['SupplierInvoiceDetailDiscountPoProrata']);
|
||||||
|
|
||||||
|
$price = $invtotal - $disprorata;
|
||||||
|
$taxPPN = doubleval($value['SupplierInvoiceTaxPercentPpn']) * $price / 100;
|
||||||
|
$kredit = round($price + $taxPPN, 2);
|
||||||
|
$totalKredit = $totalKredit + $kredit;
|
||||||
|
|
||||||
|
$items[$key]['kredit'] = $kredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($totalKredit <= 0) {
|
||||||
|
foreach ($items as $key => $value) {
|
||||||
|
$items[$key]['dpReduction'] = 0;
|
||||||
|
}
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
$runningReduction = 0;
|
||||||
|
end($items);
|
||||||
|
$lastKey = key($items);
|
||||||
|
reset($items);
|
||||||
|
|
||||||
|
foreach ($items as $key => $value) {
|
||||||
|
if ($key === $lastKey) {
|
||||||
|
$reduction = round($dpAmount - $runningReduction, 2);
|
||||||
|
} else {
|
||||||
|
$ratio = $value['kredit'] / $totalKredit;
|
||||||
|
$reduction = round($dpAmount * $ratio, 2);
|
||||||
|
$runningReduction += $reduction;
|
||||||
|
}
|
||||||
|
|
||||||
|
$items[$key]['dpReduction'] = $reduction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
function InsertJurnalTx($jurnalID, $coaID, $desc, $userID, $debit = 0, $kredit = 0): array
|
function InsertJurnalTx($jurnalID, $coaID, $desc, $userID, $debit = 0, $kredit = 0): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -172,6 +172,302 @@ Content-Type: application/json
|
|||||||
"ID": ""
|
"ID": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// upload attachment — requires multipart/form-data with file(s)
|
||||||
|
// Gunakan REST Client atau Postman. Contoh format:
|
||||||
|
// POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/uploadAttachment/
|
||||||
|
// Content-Type: multipart/form-data; boundary=----boundary
|
||||||
|
//
|
||||||
|
// ------boundary
|
||||||
|
// Content-Disposition: form-data; name="token"
|
||||||
|
//
|
||||||
|
// eyJ...
|
||||||
|
// ------boundary
|
||||||
|
// Content-Disposition: form-data; name="ponumber"
|
||||||
|
//
|
||||||
|
// PO24070001
|
||||||
|
// ------boundary
|
||||||
|
// Content-Disposition: form-data; name="poID"
|
||||||
|
//
|
||||||
|
// 1
|
||||||
|
// ------boundary
|
||||||
|
// Content-Disposition: form-data; name="contractID"
|
||||||
|
//
|
||||||
|
// 1
|
||||||
|
// ------boundary
|
||||||
|
// Content-Disposition: form-data; name="files"; filename="foto1.jpg"
|
||||||
|
// Content-Type: image/jpeg
|
||||||
|
//
|
||||||
|
// < /path/to/foto1.jpg
|
||||||
|
// ------boundary
|
||||||
|
// Content-Disposition: form-data; name="files"; filename="foto2.jpg"
|
||||||
|
// Content-Type: image/jpeg
|
||||||
|
//
|
||||||
|
// < /path/to/foto2.jpg
|
||||||
|
// ------boundary--
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}}
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// listing po asset
|
||||||
|
POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/getDaftarPoAset/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"search": "",
|
||||||
|
"currpage": 1,
|
||||||
|
"startdate": "2026-01-01",
|
||||||
|
"enddate": "2026-12-31",
|
||||||
|
"status": "All"
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// get daftar attachment
|
||||||
|
POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/getDaftarAttachment/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"contractID": 1,
|
||||||
|
"poID": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// update approval PO — verifikasi manager (level 1)
|
||||||
|
POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/updateApprovalPO/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"poID": 1,
|
||||||
|
"approvelevel": "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// get data kontrak po asset
|
||||||
|
POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/getDataKontrakPoAset/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"poID": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// create po asset
|
||||||
|
POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/createPoAsset/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"podate": "2026-07-09",
|
||||||
|
"reference": "REF-ASSET-001",
|
||||||
|
"supplierID": 1,
|
||||||
|
"typepajak": "nominal",
|
||||||
|
"valuepajak": 0,
|
||||||
|
"typediskon": "nominal",
|
||||||
|
"valuediskon": 0,
|
||||||
|
"catatan": "PO Asset Test",
|
||||||
|
"summary": {
|
||||||
|
"subtotal": 775000000,
|
||||||
|
"diskon": 37500000,
|
||||||
|
"pajak": 81125000,
|
||||||
|
"total": 818625000
|
||||||
|
},
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"M_ItemID": 123,
|
||||||
|
"ItemUnitID": 1,
|
||||||
|
"RequestQty": 2,
|
||||||
|
"SupplierPrice": 75000000,
|
||||||
|
"TempTotal": 150000000,
|
||||||
|
"DiskonType": "R",
|
||||||
|
"DiskonAmount": 0,
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"PurchaseRequestID": 1,
|
||||||
|
"PurchaseRequestDetailID": 1,
|
||||||
|
"PurchaseRequestFlagID": 1,
|
||||||
|
"M_ItemID": 123,
|
||||||
|
"ItemUnitID": 1,
|
||||||
|
"OriginalQty": 2,
|
||||||
|
"RequestQty": 2,
|
||||||
|
"SupplierPrice": 75000000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"M_ItemID": 124,
|
||||||
|
"ItemUnitID": 2,
|
||||||
|
"RequestQty": 5,
|
||||||
|
"SupplierPrice": 25000000,
|
||||||
|
"TempTotal": 125000000,
|
||||||
|
"DiskonType": "P",
|
||||||
|
"DiskonAmount": 10,
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"PurchaseRequestID": 2,
|
||||||
|
"PurchaseRequestDetailID": 2,
|
||||||
|
"PurchaseRequestFlagID": 2,
|
||||||
|
"M_ItemID": 124,
|
||||||
|
"ItemUnitID": 2,
|
||||||
|
"OriginalQty": 3,
|
||||||
|
"RequestQty": 3,
|
||||||
|
"SupplierPrice": 25000000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"PurchaseRequestID": 2,
|
||||||
|
"PurchaseRequestDetailID": 3,
|
||||||
|
"PurchaseRequestFlagID": 3,
|
||||||
|
"M_ItemID": 124,
|
||||||
|
"ItemUnitID": 2,
|
||||||
|
"OriginalQty": 2,
|
||||||
|
"RequestQty": 2,
|
||||||
|
"SupplierPrice": 25000000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"M_ItemID": 125,
|
||||||
|
"ItemUnitID": 1,
|
||||||
|
"RequestQty": 1,
|
||||||
|
"SupplierPrice": 500000000,
|
||||||
|
"TempTotal": 500000000,
|
||||||
|
"DiskonType": "R",
|
||||||
|
"DiskonAmount": 25000000,
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"PurchaseRequestID": 3,
|
||||||
|
"PurchaseRequestDetailID": 4,
|
||||||
|
"PurchaseRequestFlagID": 4,
|
||||||
|
"M_ItemID": 125,
|
||||||
|
"ItemUnitID": 1,
|
||||||
|
"OriginalQty": 1,
|
||||||
|
"RequestQty": 1,
|
||||||
|
"SupplierPrice": 500000000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"assetAttachmentID": null,
|
||||||
|
"contractName": "Kontrak Pengadaan Mesin X",
|
||||||
|
"contractDate": "2026-07-09",
|
||||||
|
"contractStart": "2026-07-09",
|
||||||
|
"contractEnd": "2027-07-09",
|
||||||
|
"contractDuration": 12,
|
||||||
|
"installmentNumber": 12,
|
||||||
|
"installmentDate": 1,
|
||||||
|
"installmentPayAmount": 12500000,
|
||||||
|
"installmentDownPaymentType": "nominal",
|
||||||
|
"installmentDownPayment": 5000000
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// edit po asset
|
||||||
|
POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/editPoAsset/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"PurchaseOrderID": 1,
|
||||||
|
"PurchaseOrderAssetContractID": 1,
|
||||||
|
"podate": "2026-07-09",
|
||||||
|
"reference": "REF-ASSET-001-UPDATED",
|
||||||
|
"supplierID": 1,
|
||||||
|
"typepajak": "percent",
|
||||||
|
"valuepajak": 11,
|
||||||
|
"typediskon": "nominal",
|
||||||
|
"valuediskon": 0,
|
||||||
|
"catatan": "PO Asset Updated",
|
||||||
|
"summary": {
|
||||||
|
"subtotal": 775000000,
|
||||||
|
"diskon": 0,
|
||||||
|
"pajak": 85250000,
|
||||||
|
"total": 860250000
|
||||||
|
},
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"M_ItemID": 123,
|
||||||
|
"ItemUnitID": 1,
|
||||||
|
"RequestQty": 3,
|
||||||
|
"SupplierPrice": 75000000,
|
||||||
|
"TempTotal": 225000000,
|
||||||
|
"DiskonType": "R",
|
||||||
|
"DiskonAmount": 0,
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"PurchaseRequestID": 1,
|
||||||
|
"PurchaseRequestDetailID": 1,
|
||||||
|
"PurchaseRequestFlagID": 1,
|
||||||
|
"M_ItemID": 123,
|
||||||
|
"ItemUnitID": 1,
|
||||||
|
"OriginalQty": 3,
|
||||||
|
"RequestQty": 3,
|
||||||
|
"SupplierPrice": 75000000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"M_ItemID": 124,
|
||||||
|
"ItemUnitID": 2,
|
||||||
|
"RequestQty": 5,
|
||||||
|
"SupplierPrice": 25000000,
|
||||||
|
"TempTotal": 125000000,
|
||||||
|
"DiskonType": "R",
|
||||||
|
"DiskonAmount": 0,
|
||||||
|
"detail": [
|
||||||
|
{
|
||||||
|
"PurchaseRequestID": 2,
|
||||||
|
"PurchaseRequestDetailID": 2,
|
||||||
|
"PurchaseRequestFlagID": 2,
|
||||||
|
"M_ItemID": 124,
|
||||||
|
"ItemUnitID": 2,
|
||||||
|
"OriginalQty": 3,
|
||||||
|
"RequestQty": 3,
|
||||||
|
"SupplierPrice": 25000000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"PurchaseRequestID": 2,
|
||||||
|
"PurchaseRequestDetailID": 3,
|
||||||
|
"PurchaseRequestFlagID": 3,
|
||||||
|
"M_ItemID": 124,
|
||||||
|
"ItemUnitID": 2,
|
||||||
|
"OriginalQty": 2,
|
||||||
|
"RequestQty": 2,
|
||||||
|
"SupplierPrice": 25000000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"assetAttachmentID": 1,
|
||||||
|
"contractName": "Kontrak Pengadaan Mesin X - Revisi",
|
||||||
|
"contractDate": "2026-07-10",
|
||||||
|
"contractStart": "2026-07-10",
|
||||||
|
"contractEnd": "2027-10-10",
|
||||||
|
"contractDuration": 15,
|
||||||
|
"installmentNumber": 15,
|
||||||
|
"installmentDate": 5,
|
||||||
|
"installmentPayAmount": 15000000,
|
||||||
|
"installmentDownPaymentType": "persen",
|
||||||
|
"installmentDownPayment": 20
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
// delete po asset
|
||||||
|
POST https://{{host}}/mockup/purchase/order/PurchaseOrderAset/deletePoAsset/
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": {{token}},
|
||||||
|
"poID": 1,
|
||||||
|
"contractID": 1,
|
||||||
|
"ponumber": "PO24070001"
|
||||||
|
}
|
||||||
|
|
||||||
### Test isValidMultiple Warehouse
|
### Test isValidMultiple Warehouse
|
||||||
### Should return True karena UnitRequest = UnitPurchase
|
### Should return True karena UnitRequest = UnitPurchase
|
||||||
GET https://{{host}}/mockup/purchase/order/PurchaseOrder/isValidMultipleWarehouse/
|
GET https://{{host}}/mockup/purchase/order/PurchaseOrder/isValidMultipleWarehouse/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -73,7 +73,7 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
$qry = $this->db->query($sql, [$user['M_BranchID'], $search]);
|
$qry = $this->db->query($sql, [$user['M_BranchID'], $search]);
|
||||||
|
|
||||||
if (!$qry) {
|
if (!$qry) {
|
||||||
$this->sys_error_db("[Error] query listing ruangan");;
|
$this->sys_error_db("[Error] query listing ruangan");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1514,23 +1514,23 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
# GET DATA RO #
|
# GET DATA RO #
|
||||||
$json_ro_before = $this->getDataROPO($ROID);
|
$json_ro_before = $this->getDataROPO($ROID);
|
||||||
$sql_ro = "SELECT
|
$sql_ro = "SELECT
|
||||||
receive_order_po.*,
|
receive_order_po.*,
|
||||||
DATE_FORMAT(ReceiveOrderPoIDate, '%d-%m-%Y') AS formatedDate,
|
DATE_FORMAT(ReceiveOrderPoIDate, '%d-%m-%Y') AS formatedDate,
|
||||||
CASE
|
CASE
|
||||||
WHEN WarehouseType = 'B'
|
WHEN WarehouseType = 'B'
|
||||||
THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName)
|
THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', M_BranchName)
|
||||||
WHEN WarehouseType = 'R'
|
WHEN WarehouseType = 'R'
|
||||||
THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName)
|
THEN CONCAT(WarehouseCode,' ', WarehouseName, ' - ', S_RegionalName)
|
||||||
ELSE ''
|
ELSE ''
|
||||||
END WarehouseName,
|
END WarehouseName,
|
||||||
WarehouseID
|
WarehouseID
|
||||||
FROM receive_order_po
|
FROM receive_order_po
|
||||||
JOIN warehouse ON ReceiveOrderPoWarehouseID = WarehouseID
|
JOIN warehouse ON ReceiveOrderPoWarehouseID = WarehouseID
|
||||||
JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID
|
JOIN s_regional ON WarehouseS_RegionalID = S_RegionalID
|
||||||
AND S_RegionalIsActive = 'Y'
|
AND S_RegionalIsActive = 'Y'
|
||||||
LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID
|
LEFT JOIN m_branch ON WarehouseM_BranchID = M_BranchID
|
||||||
AND M_BranchIsActive = 'Y'
|
AND M_BranchIsActive = 'Y'
|
||||||
WHERE ReceiveOrderPoID = ?";
|
WHERE ReceiveOrderPoID = ?";
|
||||||
$que_ro = $this->db->query($sql_ro, [$ROID]);
|
$que_ro = $this->db->query($sql_ro, [$ROID]);
|
||||||
if (!$que_ro) {
|
if (!$que_ro) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1545,23 +1545,23 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sql_detail_ro = "SELECT
|
$sql_detail_ro = "SELECT
|
||||||
receive_order_po_detail.*,
|
receive_order_po_detail.*,
|
||||||
PurchaseOrderID,
|
PurchaseOrderID,
|
||||||
PurchaseOrderNumber,
|
PurchaseOrderNumber,
|
||||||
PurchaseOrderTaxPercentPph,
|
PurchaseOrderTaxPercentPph,
|
||||||
PurchaseOrderTaxPercentPpn,
|
PurchaseOrderTaxPercentPpn,
|
||||||
PurchaseOrderSummaryDiscountAmount as DiscountPerItem,
|
PurchaseOrderSummaryDiscountAmount as DiscountPerItem,
|
||||||
PurchaseOrderSummaryQty as QtyAllPO,
|
PurchaseOrderSummaryQty as QtyAllPO,
|
||||||
PurchaseOrderSummaryTotal as TotalAllPO,
|
PurchaseOrderSummaryTotal as TotalAllPO,
|
||||||
PurchaseOrderDiscountPercent AS DiscPOPercent,
|
PurchaseOrderDiscountPercent AS DiscPOPercent,
|
||||||
PurchaseOrderDiscountAmount AS DiscPORupiah
|
PurchaseOrderDiscountAmount AS DiscPORupiah
|
||||||
FROM receive_order_po_detail
|
FROM receive_order_po_detail
|
||||||
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
||||||
JOIN purchase_order_summary ON ReceiveOrderPoDetailPurchaseOrderSummaryID = PurchaseOrderSummaryID
|
JOIN purchase_order_summary ON ReceiveOrderPoDetailPurchaseOrderSummaryID = PurchaseOrderSummaryID
|
||||||
AND PurchaseOrderSummaryIsActive = 'Y'
|
AND PurchaseOrderSummaryIsActive = 'Y'
|
||||||
WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
|
WHERE ReceiveOrderPoDetailReceiveOrderPoID = ?
|
||||||
AND ReceiveOrderPoDetailIsActive='Y'
|
AND ReceiveOrderPoDetailIsActive='Y'
|
||||||
GROUP BY ReceiveOrderPoDetailID";
|
GROUP BY ReceiveOrderPoDetailID";
|
||||||
$que_detail_ro = $this->db->query($sql_detail_ro, [$ROID]);
|
$que_detail_ro = $this->db->query($sql_detail_ro, [$ROID]);
|
||||||
if (!$que_detail_ro) {
|
if (!$que_detail_ro) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1572,10 +1572,10 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
|
|
||||||
# UPDATE STATUS RO #
|
# UPDATE STATUS RO #
|
||||||
$sql_update_ro = "UPDATE receive_order_po SET
|
$sql_update_ro = "UPDATE receive_order_po SET
|
||||||
ReceiveOrderPoConfirmed = 'Y',
|
ReceiveOrderPoConfirmed = 'Y',
|
||||||
ReceiveOrderPoConfirmedDate = NOW(),
|
ReceiveOrderPoConfirmedDate = NOW(),
|
||||||
ReceiveOrderPoConfirmedUserID = ?
|
ReceiveOrderPoConfirmedUserID = ?
|
||||||
WHERE ReceiveOrderPoID = ?";
|
WHERE ReceiveOrderPoID = ?";
|
||||||
$que_update_ro = $this->db->query($sql_update_ro, [$user['M_UserID'], $ROID]);
|
$que_update_ro = $this->db->query($sql_update_ro, [$user['M_UserID'], $ROID]);
|
||||||
if (!$que_update_ro) {
|
if (!$que_update_ro) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -1594,8 +1594,8 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
$jurnal_number = $que_jrnl_num->row_array()['numbering'];
|
$jurnal_number = $que_jrnl_num->row_array()['numbering'];
|
||||||
|
|
||||||
$sql_periode = "SELECT periodeID FROM periode
|
$sql_periode = "SELECT periodeID FROM periode
|
||||||
WHERE DATE(NOW()) BETWEEN periodeStartDate AND periodeEndDate
|
WHERE DATE(NOW()) BETWEEN periodeStartDate AND periodeEndDate
|
||||||
AND periodeIsActive= 'Y' AND periodeIsClosed = 'N'";
|
AND periodeIsActive= 'Y' AND periodeIsClosed = 'N'";
|
||||||
$que_periode = $this->db->query($sql_periode, []);
|
$que_periode = $this->db->query($sql_periode, []);
|
||||||
if (!$que_periode) {
|
if (!$que_periode) {
|
||||||
$this->sys_error_db("[Error] get periode", $this->db);
|
$this->sys_error_db("[Error] get periode", $this->db);
|
||||||
@@ -1631,17 +1631,17 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
|
|
||||||
# INSERT JURNAL HEADER #
|
# INSERT JURNAL HEADER #
|
||||||
$sql_head_jurnal = "INSERT INTO jurnal (
|
$sql_head_jurnal = "INSERT INTO jurnal (
|
||||||
jurnalM_BranchCompanyID,
|
jurnalM_BranchCompanyID,
|
||||||
JurnalS_RegionalID,
|
JurnalS_RegionalID,
|
||||||
jurnalM_BranchCode,
|
jurnalM_BranchCode,
|
||||||
jurnalperiodeID,
|
jurnalperiodeID,
|
||||||
jurnalNo,
|
jurnalNo,
|
||||||
jurnalTitle,
|
jurnalTitle,
|
||||||
jurnalDescription,
|
jurnalDescription,
|
||||||
jurnalDate,
|
jurnalDate,
|
||||||
jurnalJurnalTypeID,
|
jurnalJurnalTypeID,
|
||||||
jurnalM_UserID
|
jurnalM_UserID
|
||||||
) VALUES (?,?,?,?,?,?,?,NOW(),?,?)";
|
) VALUES (?,?,?,?,?,?,?,NOW(),?,?)";
|
||||||
$que_head_jurnal = $this->db->query($sql_head_jurnal, [
|
$que_head_jurnal = $this->db->query($sql_head_jurnal, [
|
||||||
$user['M_BranchCompanyID'],
|
$user['M_BranchCompanyID'],
|
||||||
$user['S_RegionalID'],
|
$user['S_RegionalID'],
|
||||||
@@ -1668,9 +1668,9 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
foreach ($data_detail_ro as $key => $detail) {
|
foreach ($data_detail_ro as $key => $detail) {
|
||||||
# UPDATE PO Summary #
|
# UPDATE PO Summary #
|
||||||
$sql_posummary = "UPDATE purchase_order_summary SET
|
$sql_posummary = "UPDATE purchase_order_summary SET
|
||||||
PurchaseOrderSummaryQtyReceived = PurchaseOrderSummaryQtyReceived + ?
|
PurchaseOrderSummaryQtyReceived = PurchaseOrderSummaryQtyReceived + ?
|
||||||
WHERE PurchaseOrderSummaryIsActive = 'Y'
|
WHERE PurchaseOrderSummaryIsActive = 'Y'
|
||||||
AND PurchaseOrderSummaryID = ?";
|
AND PurchaseOrderSummaryID = ?";
|
||||||
$que_posummary = $this->db->query($sql_posummary, [
|
$que_posummary = $this->db->query($sql_posummary, [
|
||||||
intval($detail['ReceiveOrderPoDetailQty']),
|
intval($detail['ReceiveOrderPoDetailQty']),
|
||||||
$detail['ReceiveOrderPoDetailPurchaseOrderSummaryID']
|
$detail['ReceiveOrderPoDetailPurchaseOrderSummaryID']
|
||||||
@@ -1705,22 +1705,38 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_coa_inv = "SELECT
|
$sql_invcoa = "SELECT
|
||||||
CoaMapInventarisCoaID,
|
COALESCE(
|
||||||
CoaMapInventarisCoaNo,
|
i.M_InventarisItemCoaMappingID,
|
||||||
CoaMapInventarisCoaDesc
|
g.M_InventarisCoaMappingID
|
||||||
FROM coa_map_inventaris
|
) AS MappingID,
|
||||||
WHERE CoaMapInventarisM_InventarisGolID = ?
|
COALESCE(
|
||||||
AND CoaMapInventarisIsActive = 'Y'";
|
i.M_InventarisItemCoaMappingCoaInventarisID,
|
||||||
$que_coa_inv = $this->db->query($sql_coa_inv, [$item_cek['M_ItemM_InventarisGolID']]);
|
g.M_InventarisCoaMappingCoaInventarisID
|
||||||
if (!$que_coa_inv) {
|
) AS CoaInventarisID,
|
||||||
|
c.coaDescription AS CoaInventarisDesc
|
||||||
|
FROM (SELECT 1) AS inventory
|
||||||
|
LEFT JOIN m_inventaris_item_coa_mapping i
|
||||||
|
ON i.M_InventarisItemCoaMappingM_ItemID = ?
|
||||||
|
AND i.M_InventarisItemCoaMappingIsActive = 'Y'
|
||||||
|
LEFT JOIN m_inventaris_coa_mapping g
|
||||||
|
ON g.M_InventarisCoaMappingM_InventarisGolID = ?
|
||||||
|
AND g.M_InventarisCoaMappingIsActive = 'Y'
|
||||||
|
LEFT JOIN coa c
|
||||||
|
ON c.coaID = COALESCE(i.M_InventarisItemCoaMappingCoaInventarisID, g.M_InventarisCoaMappingCoaInventarisID)
|
||||||
|
AND c.coaIsActive = 'Y'";
|
||||||
|
$que_invcoa = $this->db->query($sql_invcoa, [
|
||||||
|
$item_cek['M_ItemID'],
|
||||||
|
$item_cek['M_ItemM_InventarisGolID']
|
||||||
|
]);
|
||||||
|
if (!$que_invcoa) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db("[Error] failed to get coa biaya item inventaris");
|
$this->sys_error_db("[Error] failed to get coa biaya item inventaris");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$iteminv_coa = $que_coa_inv->row_array();
|
$iteminv_coa = $que_invcoa->row_array();
|
||||||
|
|
||||||
if (empty($iteminv_coa['CoaMapInventarisCoaID'])) {
|
if (empty($iteminv_coa['CoaInventarisID'])) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
$this->sys_error_db("[Error] coa gol inventaris not found");
|
$this->sys_error_db("[Error] coa gol inventaris not found");
|
||||||
exit;
|
exit;
|
||||||
@@ -1740,8 +1756,8 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
) VALUES (?,?,?,?,?,?)";
|
) VALUES (?,?,?,?,?,?)";
|
||||||
$que_tx_jurnal = $this->db->query($sql_tx_jurnal, [
|
$que_tx_jurnal = $this->db->query($sql_tx_jurnal, [
|
||||||
$jurnal_ID,
|
$jurnal_ID,
|
||||||
$iteminv_coa['CoaMapInventarisCoaID'],
|
$iteminv_coa['CoaInventarisID'],
|
||||||
$iteminv_coa['CoaMapInventarisCoaDesc'],
|
$iteminv_coa['CoaInventarisDesc'],
|
||||||
$debet,
|
$debet,
|
||||||
0,
|
0,
|
||||||
$user['M_UserID']
|
$user['M_UserID']
|
||||||
@@ -1754,7 +1770,7 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
}
|
}
|
||||||
$juranl_tx_ID = $this->db->insert_id();
|
$juranl_tx_ID = $this->db->insert_id();
|
||||||
$each_desc[] = "- Add detail Jurnal debet {$item_cek['M_ItemDesc']}
|
$each_desc[] = "- Add detail Jurnal debet {$item_cek['M_ItemDesc']}
|
||||||
{$iteminv_coa['CoaMapInventarisCoaDesc']} sejumlah {$this->formatRupiah($debet)}";
|
{$iteminv_coa['CoaInventarisDesc']} sejumlah {$this->formatRupiah($debet)}";
|
||||||
|
|
||||||
# INSERT JURNAL ADDON #
|
# INSERT JURNAL ADDON #
|
||||||
$sql_addon_jurnal = "INSERT INTO jurnal_addon (
|
$sql_addon_jurnal = "INSERT INTO jurnal_addon (
|
||||||
@@ -1862,8 +1878,8 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
|
|
||||||
// save diskon prorata
|
// save diskon prorata
|
||||||
$sql_save_diskon = "UPDATE receive_order_po_detail SET
|
$sql_save_diskon = "UPDATE receive_order_po_detail SET
|
||||||
ReceiveOrderPoDetailDiskonPoProrata = ?
|
ReceiveOrderPoDetailDiskonPoProrata = ?
|
||||||
WHERE ReceiveOrderPoDetailID = ?";
|
WHERE ReceiveOrderPoDetailID = ?";
|
||||||
$que_save_diskon = $this->db->query($sql_save_diskon, [
|
$que_save_diskon = $this->db->query($sql_save_diskon, [
|
||||||
$diskon_prorata_item,
|
$diskon_prorata_item,
|
||||||
$detail['ReceiveOrderPoDetailID']
|
$detail['ReceiveOrderPoDetailID']
|
||||||
@@ -1898,9 +1914,9 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
// update stock based on batch
|
// update stock based on batch
|
||||||
foreach ($batch_list as $key => $batch) {
|
foreach ($batch_list as $key => $batch) {
|
||||||
$sql_cek_stock = "SELECT *
|
$sql_cek_stock = "SELECT *
|
||||||
FROM stock s
|
FROM stock s
|
||||||
JOIN m_item i ON s.StockItemID = i.M_ItemID
|
JOIN m_item i ON s.StockItemID = i.M_ItemID
|
||||||
WHERE s.StockItemID = ?
|
WHERE s.StockItemID = ?
|
||||||
AND s.StockItemUnitID = ?
|
AND s.StockItemUnitID = ?
|
||||||
AND s.StockWarehouseID = ?
|
AND s.StockWarehouseID = ?
|
||||||
AND i.M_ItemItem_CategoryID = ?";
|
AND i.M_ItemItem_CategoryID = ?";
|
||||||
@@ -1944,20 +1960,6 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
$this->sys_error_db("[Error] insert update stock");
|
$this->sys_error_db("[Error] insert update stock");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert stockid barcode barang
|
|
||||||
$sql_update_barcode = "UPDATE t_barcode_barang SET
|
|
||||||
T_BarcodeBarangStockID = ?
|
|
||||||
WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?";
|
|
||||||
$qry_update_barcode = $this->db->query($sql_update_barcode, [
|
|
||||||
$stock_ID,
|
|
||||||
$detail['ReceiveOrderPoDetailID']
|
|
||||||
]);
|
|
||||||
if (!$qry_update_barcode) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] update barcode stockID", $this->db);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$sql_insert_stock = "INSERT INTO stock (
|
$sql_insert_stock = "INSERT INTO stock (
|
||||||
StockWarehouseAlmariID,
|
StockWarehouseAlmariID,
|
||||||
@@ -1985,23 +1987,9 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stockID = $this->db->insert_id();
|
$stock_ID = $this->db->insert_id();
|
||||||
$stock_qty_ori = 0;
|
$stock_qty_ori = 0;
|
||||||
$stock_qty_end = intval($batch['qty']);
|
$stock_qty_end = intval($batch['qty']);
|
||||||
|
|
||||||
// insert stockid barcode barang
|
|
||||||
$sql_update_barcode = "UPDATE t_barcode_barang SET
|
|
||||||
T_BarcodeBarangStockID = ?
|
|
||||||
WHERE T_BarcodeBarangReceiveOrderPoDetailID = ?";
|
|
||||||
$qry_update_barcode = $this->db->query($sql_update_barcode, [
|
|
||||||
$stockID,
|
|
||||||
$detail['ReceiveOrderPoDetailID']
|
|
||||||
]);
|
|
||||||
if (!$qry_update_barcode) {
|
|
||||||
$this->db->trans_rollback();
|
|
||||||
$this->sys_error_db("[Error] update barcode stockID", $this->db);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert stock card
|
// insert stock card
|
||||||
@@ -2095,14 +2083,14 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
// insert jurnal tx for GRNI
|
// insert jurnal tx for GRNI
|
||||||
$total_grni = round($total_debet - ($total_discount_item + $total_discount_po), 2) + $ship_cost;
|
$total_grni = round($total_debet - ($total_discount_item + $total_discount_po), 2) + $ship_cost;
|
||||||
$sql_grni = "INSERT INTO jurnal_tx (
|
$sql_grni = "INSERT INTO jurnal_tx (
|
||||||
jurnalTxJurnalID,
|
jurnalTxJurnalID,
|
||||||
jurnalTxCoaID,
|
jurnalTxCoaID,
|
||||||
jurnalTxDescription,
|
jurnalTxDescription,
|
||||||
jurnalTxDebit,
|
jurnalTxDebit,
|
||||||
jurnalTxCredit,
|
jurnalTxCredit,
|
||||||
jurnalTxM_UserID
|
jurnalTxM_UserID
|
||||||
) SELECT ?, coaID, coaDescription, 0, ?, ?
|
) SELECT ?, coaID, coaDescription, 0, ?, ?
|
||||||
FROM coa WHERE coaAccountNo = '2110100030' LIMIT 1";
|
FROM coa WHERE coaAccountNo = '2110100030' LIMIT 1";
|
||||||
$que_grni = $this->db->query($sql_grni, [$jurnal_ID, $total_grni, $user['M_UserID']]);
|
$que_grni = $this->db->query($sql_grni, [$jurnal_ID, $total_grni, $user['M_UserID']]);
|
||||||
if (!$que_grni) {
|
if (!$que_grni) {
|
||||||
$this->db->trans_rollback();
|
$this->db->trans_rollback();
|
||||||
@@ -2112,13 +2100,13 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
$grni_jurnal_id = $this->db->insert_id();
|
$grni_jurnal_id = $this->db->insert_id();
|
||||||
|
|
||||||
$sql_addon_grni = "INSERT INTO jurnal_addon (
|
$sql_addon_grni = "INSERT INTO jurnal_addon (
|
||||||
jurnalAddOnJurnalID,
|
jurnalAddOnJurnalID,
|
||||||
jurnalAddOnJurnalTxID,
|
jurnalAddOnJurnalTxID,
|
||||||
jurnalAddOnCode,
|
jurnalAddOnCode,
|
||||||
jurnalAddOnValue,
|
jurnalAddOnValue,
|
||||||
jurnalAddOnCreated,
|
jurnalAddOnCreated,
|
||||||
jurnalAddOnCreatedUserID
|
jurnalAddOnCreatedUserID
|
||||||
) VALUES (?,?,'RONUMB',?,NOW(),?)";
|
) VALUES (?,?,'RONUMB',?,NOW(),?)";
|
||||||
$que_addon_grni = $this->db->query($sql_addon_grni, [
|
$que_addon_grni = $this->db->query($sql_addon_grni, [
|
||||||
$jurnal_ID,
|
$jurnal_ID,
|
||||||
$grni_jurnal_id,
|
$grni_jurnal_id,
|
||||||
@@ -2344,22 +2332,22 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
$this->db->trans_begin();
|
$this->db->trans_begin();
|
||||||
|
|
||||||
$sql_insert = "INSERT INTO receive_order_po_inspeksi (
|
$sql_insert = "INSERT INTO receive_order_po_inspeksi (
|
||||||
ReceiveOrderPoInspeksiReceiveOrderPoDetailID,
|
ReceiveOrderPoInspeksiReceiveOrderPoDetailID,
|
||||||
ReceiveOrderPoInspeksiQtyPesan,
|
ReceiveOrderPoInspeksiQtyPesan,
|
||||||
ReceiveOrderPoInspeksiQtyActual,
|
ReceiveOrderPoInspeksiQtyActual,
|
||||||
ReceiveOrderPoInspeksiPricePesan,
|
ReceiveOrderPoInspeksiPricePesan,
|
||||||
ReceiveOrderPoInspeksiPriceActual,
|
ReceiveOrderPoInspeksiPriceActual,
|
||||||
ReceiveOrderPoInspeksiDatePesan,
|
ReceiveOrderPoInspeksiDatePesan,
|
||||||
ReceiveOrderPoInspeksiDateActual,
|
ReceiveOrderPoInspeksiDateActual,
|
||||||
ReceiveOrderPoInspeksiExpireDate,
|
ReceiveOrderPoInspeksiExpireDate,
|
||||||
ReceiveOrderPoInspeksiKeadaanKemasan,
|
ReceiveOrderPoInspeksiKeadaanKemasan,
|
||||||
ReceiveOrderPoInspeksiKondisiPengiriman,
|
ReceiveOrderPoInspeksiKondisiPengiriman,
|
||||||
ReceiveOrderPoInspeksiSimpulan,
|
ReceiveOrderPoInspeksiSimpulan,
|
||||||
ReceiveOrderPoInspeksiCatatan,
|
ReceiveOrderPoInspeksiCatatan,
|
||||||
ReceiveOrderPoInspeksiStaffPenerima,
|
ReceiveOrderPoInspeksiStaffPenerima,
|
||||||
ReceiveOrderPoInspeksiStaffPengirim,
|
ReceiveOrderPoInspeksiStaffPengirim,
|
||||||
ReceiveOrderPoInspeksiUserID
|
ReceiveOrderPoInspeksiUserID
|
||||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||||
$que_insert = $this->db->query($sql_insert, [
|
$que_insert = $this->db->query($sql_insert, [
|
||||||
$ROdetailID,
|
$ROdetailID,
|
||||||
$inspeksi['qty_po'],
|
$inspeksi['qty_po'],
|
||||||
@@ -2705,7 +2693,29 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
|
|
||||||
# generate barcode number each inventory item #
|
# generate barcode number each inventory item #
|
||||||
$noBarcode = $this->generateNoBarcode($user, $param['ruanganID'], 'BNP', $item['ReceiveOrderPoItemID']);
|
$noBarcode = $this->generateNoBarcode($user, $param['ruanganID'], 'BNP', $item['ReceiveOrderPoItemID']);
|
||||||
|
|
||||||
|
# check if item already in stock #
|
||||||
|
$sql_cekstock = "SELECT StockID
|
||||||
|
FROM stock
|
||||||
|
JOIN warehouse ON WarehouseID = StockWarehouseID
|
||||||
|
AND WarehouseIsActive = 'Y'
|
||||||
|
WHERE WarehouseM_BranchID = ?
|
||||||
|
AND StockItemID = ?
|
||||||
|
AND StockItemUnitID = ?";
|
||||||
|
$que_cekstock = $this->db->query($sql_cekstock, [
|
||||||
|
$user['M_BranchID'],
|
||||||
|
$item['ReceiveOrderPoItemID'],
|
||||||
|
$item['ReceiveOrderPoItemUnitID'],
|
||||||
|
]);
|
||||||
|
if (!$que_cekstock) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] query cek stock");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$stockID = $que_cekstock->row_array()['StockID'];
|
||||||
|
|
||||||
$sql_insert_barcode = "INSERT INTO t_barcode_barang(
|
$sql_insert_barcode = "INSERT INTO t_barcode_barang(
|
||||||
|
T_BarcodeBarangStockID,
|
||||||
T_BarcodeBarangReceiveOrderPoID,
|
T_BarcodeBarangReceiveOrderPoID,
|
||||||
T_BarcodeBarangReceiveOrderPoDetailID,
|
T_BarcodeBarangReceiveOrderPoDetailID,
|
||||||
T_BarcodeBarangRefType,
|
T_BarcodeBarangRefType,
|
||||||
@@ -2717,8 +2727,9 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
T_BarcodeBarangIsActive,
|
T_BarcodeBarangIsActive,
|
||||||
T_BarcodeBarangUserID,
|
T_BarcodeBarangUserID,
|
||||||
T_BarcodeBarangCreated
|
T_BarcodeBarangCreated
|
||||||
) VALUES(?,?,'PO',?,?,?,?,?,'Y',?,NOW())";
|
) VALUES(?,?,?,'PO',?,?,?,?,?,'Y',?,NOW())";
|
||||||
$que_insert_barcode = $this->db->query($sql_insert_barcode, [
|
$que_insert_barcode = $this->db->query($sql_insert_barcode, [
|
||||||
|
$stockID,
|
||||||
$param['receiveOrderPoID'],
|
$param['receiveOrderPoID'],
|
||||||
$item['ReceiveOrderPoDetailID'],
|
$item['ReceiveOrderPoDetailID'],
|
||||||
$item['ReceiveOrderPoItemID'],
|
$item['ReceiveOrderPoItemID'],
|
||||||
@@ -2736,6 +2747,27 @@ class ReceiveItemPoInventaris extends MY_Controller
|
|||||||
|
|
||||||
$barcodeID = $this->db->insert_id();
|
$barcodeID = $this->db->insert_id();
|
||||||
|
|
||||||
|
# insert stock inventaris #
|
||||||
|
$sql_stockinventaris = "INSERT INTO stock_inventory (
|
||||||
|
StockInventoryStockID,
|
||||||
|
StockInventoryRuanganID,
|
||||||
|
StockInventoryBarcode,
|
||||||
|
StockInventoryBranchID,
|
||||||
|
StockInventoryCreatedUserID
|
||||||
|
) VALUES (?,?,?,?,?)";
|
||||||
|
$que_stockinventaris = $this->db->query($sql_stockinventaris, [
|
||||||
|
$stockID,
|
||||||
|
$param['ruanganID'],
|
||||||
|
$noBarcode,
|
||||||
|
$user['M_BranchID'],
|
||||||
|
$user['M_UserID']
|
||||||
|
]);
|
||||||
|
if (!$que_stockinventaris) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("[Error] insert into table stock inventaris");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
# insert each inventory handover detail #
|
# insert each inventory handover detail #
|
||||||
$sql_insert_handover_detail = "INSERT INTO asset_handover_detail(
|
$sql_insert_handover_detail = "INSERT INTO asset_handover_detail(
|
||||||
AssetHandoverDetailAssetHandoverID,
|
AssetHandoverDetailAssetHandoverID,
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ class ReceiveItemPoV2 extends MY_Controller {
|
|||||||
AND ReceiveOrderPoIDate BETWEEN DATE(?) AND DATE(?)
|
AND ReceiveOrderPoIDate BETWEEN DATE(?) AND DATE(?)
|
||||||
AND ReceiveOrderPoS_RegionalID = ?
|
AND ReceiveOrderPoS_RegionalID = ?
|
||||||
AND ReceiveOrderPoM_BranchCode LIKE ?
|
AND ReceiveOrderPoM_BranchCode LIKE ?
|
||||||
AND ReceiveOrderPoID NOT IN (
|
AND ReceiveOrderPoID IN (
|
||||||
SELECT DISTINCT ReceiveOrderPoDetailReceiveOrderPoID
|
SELECT DISTINCT ReceiveOrderPoDetailReceiveOrderPoID
|
||||||
FROM receive_order_po_detail
|
FROM receive_order_po_detail
|
||||||
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
@host = https://accone.aplikasi.web.id/one-api
|
||||||
|
@date = 2026-07-14
|
||||||
|
@coaBayarID = 1110100001
|
||||||
|
@coaHutangID = 2110100030
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# JurnalPiCicilanOrderAset — Contoh Pemanggilan Endpoint
|
||||||
|
# =============================================================================
|
||||||
|
# Urutan penggunaan yang disarankan:
|
||||||
|
# 1. ListEligiblePurchaseOrderAssetContracts → lihat kontrak yang akan diproses
|
||||||
|
# 2. GenerateJournalsFromContracts (dryRun=Y) → simulasi tanpa simpan ke DB
|
||||||
|
# 3. GenerateJournalsFromContracts (dryRun=N) → generate jurnal sesungguhnya
|
||||||
|
# 4. CreateJournal → buat jurnal manual 1 per 1
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
### 1. Lihat kontrak aset yang eligible untuk dibuatkan jurnal bulan ini
|
||||||
|
GET {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/ListEligiblePurchaseOrderAssetContracts
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"startDate": "2026-07-01",
|
||||||
|
"endDate": "2026-07-31"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 2. Simulasi generate jurnal (dryRun=Y) — tidak menyimpan ke database
|
||||||
|
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"date" : "{{date}}",
|
||||||
|
"dryRun" : "Y"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 3. Generate jurnal untuk semua kontrak eligible bulan ini (sesungguhnya)
|
||||||
|
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"date" : "{{date}}",
|
||||||
|
"dryRun" : "N"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 4. Generate jurnal untuk 1 kontrak tertentu saja (contractID=99)
|
||||||
|
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"date" : "{{date}}",
|
||||||
|
"dryRun" : "Y",
|
||||||
|
"contractID" : 00
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 5. Buat jurnal manual (1 jurnal, input detail sendiri)
|
||||||
|
POST {{host}}/index.php/mockup/scheduler/JurnalPiCicilanOrderAset/CreateJournal
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"date" : "{{date}}",
|
||||||
|
"branchCode" : "BA",
|
||||||
|
"regionalID" : 8,
|
||||||
|
"branchCompanyID": 1,
|
||||||
|
"jurnalTypeID" : 11,
|
||||||
|
"title" : "Jurnal PI Cicilan Order Aset",
|
||||||
|
"description" : "Cicilan ke-1 dari 12 | Kontrak Kendaraan Operasional | Periode 2026-07",
|
||||||
|
"details" : [
|
||||||
|
{
|
||||||
|
"coaID" : {{coaHutangID}},
|
||||||
|
"description": "Hutang cicilan aset - Kendaraan Operasional",
|
||||||
|
"debit" : 15000000,
|
||||||
|
"credit" : 0,
|
||||||
|
"addonCode" : "PIINSTALMENT",
|
||||||
|
"addonValue" : "42",
|
||||||
|
"mItemID" : 123
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"coaID" : {{coaBayarID}},
|
||||||
|
"description": "Pembayaran cicilan aset - Kendaraan Operasional",
|
||||||
|
"debit" : 0,
|
||||||
|
"credit" : 15000000,
|
||||||
|
"addonCode" : "PIINSTALMENT",
|
||||||
|
"addonValue" : "42",
|
||||||
|
"mItemID" : 123
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,970 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JurnalPiCicilanOrderAset
|
||||||
|
*
|
||||||
|
* Controller scheduler untuk membuat jurnal akuntansi atas Purchase Invoice (PI)
|
||||||
|
* cicilan order aset secara otomatis.
|
||||||
|
*
|
||||||
|
* Alur bisnis proses:
|
||||||
|
* 1. Validasi parameter input (tanggal, branchCode, title, description, details)
|
||||||
|
* 2. Insert header jurnal ke tabel `jurnal`
|
||||||
|
* - Nomor jurnal di-generate via fn_numbering('J')
|
||||||
|
* - Tipe jurnal: PAYMENT
|
||||||
|
* - Berisi: title, description, tanggal, regionalID, kode cabang, branchCompanyID
|
||||||
|
* 3. Insert baris transaksi ke tabel `jurnal_tx` (untuk setiap baris cicilan)
|
||||||
|
* - Referensi ke jurnalID header
|
||||||
|
* - COA (Chart of Account) dan deskripsinya:
|
||||||
|
* * Sisi hutang cicilan → nilai DEBIT (diambil dari HutangCoaID di fa_class)
|
||||||
|
* * Sisi pembayaran cicilan → nilai KREDIT (diambil dari ItemCoaID di fa_class)
|
||||||
|
* 4. Insert data tambahan ke tabel `jurnal_addon` (jika ada addonValue atau mItemID)
|
||||||
|
* - Referensi ke jurnalID dan jurnalTxID
|
||||||
|
* - Berisi: addonCode (default: "PIINSTALMENT"), addonValue, mItemID
|
||||||
|
*
|
||||||
|
* Endpoint:
|
||||||
|
* POST /mockup/scheduler/JurnalPiCicilanOrderAset/CreateJournal
|
||||||
|
* POST /mockup/scheduler/JurnalPiCicilanOrderAset/GenerateJournalsFromContracts
|
||||||
|
* GET /mockup/scheduler/JurnalPiCicilanOrderAset/ListEligiblePurchaseOrderAssetContracts
|
||||||
|
*/
|
||||||
|
class JurnalPiCicilanOrderAset extends MY_Controller
|
||||||
|
{
|
||||||
|
var $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint default — menampilkan nama controller sebagai penanda aktif.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Jurnal PI Cicilan Order Aset";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor — inisialisasi parent controller.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateJournal — Membuat jurnal PI cicilan order aset.
|
||||||
|
*
|
||||||
|
* Proses bisnis:
|
||||||
|
* 1. Validasi semua parameter wajib: date, branchCode, title, description, details
|
||||||
|
* 2. Ambil periodeID dari tanggal transaksi (tabel periode)
|
||||||
|
* 3. Ambil regionalID dari branchCode (tabel m_branch)
|
||||||
|
* 4. Ambil branchCompanyID dari branchCode (tabel m_branch_companydetail)
|
||||||
|
* 5. Ambil jurnalTypeID dari kode tipe jurnal (default: "PAYMENT")
|
||||||
|
* 6. Generate nomor jurnal otomatis via fn_numbering('J')
|
||||||
|
* 7. Validasi balance: total debit harus sama dengan total credit
|
||||||
|
* 8. INSERT header jurnal ke tabel `jurnal`:
|
||||||
|
* - jurnalNo : nomor jurnal hasil generate
|
||||||
|
* - jurnalJurnalTypeID: tipe PAYMENT
|
||||||
|
* - jurnalTitle : judul jurnal
|
||||||
|
* - jurnalDescription: keterangan jurnal
|
||||||
|
* - jurnalDate : tanggal transaksi
|
||||||
|
* - JurnalS_RegionalID: ID regional cabang
|
||||||
|
* - jurnalM_BranchCode: kode cabang
|
||||||
|
* 9. Untuk setiap baris detail, INSERT ke `jurnal_tx`:
|
||||||
|
* - jurnalTxJurnalID : referensi ke header jurnal
|
||||||
|
* - jurnalTxCoaID : COA yang digunakan (hutang cicilan / kas/bank)
|
||||||
|
* - jurnalTxDescription: keterangan baris (nama cicilan/aset)
|
||||||
|
* - jurnalTxDebit : nilai hutang (sisi debit)
|
||||||
|
* - jurnalTxCredit : nilai bayar (sisi kredit)
|
||||||
|
* 10. Jika ada addonValue atau mItemID, INSERT ke `jurnal_addon`:
|
||||||
|
* - jurnalAddOnJurnalID : referensi ke header jurnal
|
||||||
|
* - jurnalAddOnJurnalTxID: referensi ke baris jurnal_tx
|
||||||
|
* - jurnalAddOnCode : kode addon (default: "PIINSTALMENT")
|
||||||
|
* - jurnalAddOnValue : nilai tambahan (misal: nomor PI/kontrak)
|
||||||
|
* - jurnalAddOnM_ItemID : ID item aset yang terkait
|
||||||
|
*
|
||||||
|
* Parameter (POST JSON):
|
||||||
|
* - date : Tanggal jurnal (YYYY-MM-DD). Default: hari ini.
|
||||||
|
* - branchCode : Kode cabang. WAJIB.
|
||||||
|
* - title : Judul jurnal. WAJIB.
|
||||||
|
* - description : Keterangan jurnal. WAJIB.
|
||||||
|
* - details : Array baris transaksi. WAJIB, minimal 1 baris.
|
||||||
|
* - coaID : ID Chart of Account. WAJIB per baris.
|
||||||
|
* - description : Keterangan baris.
|
||||||
|
* - debit : Nilai debit (hutang cicilan).
|
||||||
|
* - credit : Nilai kredit (pembayaran cicilan).
|
||||||
|
* - addonValue : (opsional) Nilai addon, misal nomor PI.
|
||||||
|
* - mItemID : (opsional) ID item aset.
|
||||||
|
* - addonCode : (opsional) Kode addon. Default: "PIINSTALMENT".
|
||||||
|
* - periodeID : (opsional) ID periode. Default: diambil dari tanggal.
|
||||||
|
* - regionalID : (opsional) ID regional. Default: diambil dari branchCode.
|
||||||
|
* - branchCompanyID: (opsional) ID branch company. Default: diambil dari branchCode.
|
||||||
|
* - jurnalTypeID : (opsional) ID tipe jurnal. Default: diambil dari jurnalTypeCode.
|
||||||
|
* - jurnalTypeCode: (opsional) Kode tipe jurnal. Default: "PAYMENT".
|
||||||
|
* - userID : ID user yang membuat jurnal.
|
||||||
|
*
|
||||||
|
* @return JSON { jurnalID, jurnalNo, detailCount, addonCount }
|
||||||
|
*/
|
||||||
|
public function CreateJournal()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$date = isset($para["date"]) && $para["date"] != "" ? $para["date"] : date("Y-m-d");
|
||||||
|
if (!$this->isValidDate($date)) {
|
||||||
|
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$branchCode = isset($para["branchCode"]) ? trim($para["branchCode"]) : "";
|
||||||
|
if ($branchCode == "") {
|
||||||
|
throw new Exception("branchCode wajib diisi.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = isset($para["title"]) ? trim($para["title"]) : "";
|
||||||
|
if ($title == "") {
|
||||||
|
throw new Exception("title wajib diisi.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$description = isset($para["description"]) ? trim($para["description"]) : "";
|
||||||
|
if ($description == "") {
|
||||||
|
throw new Exception("description wajib diisi.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$details = isset($para["details"]) && is_array($para["details"]) ? $para["details"] : [];
|
||||||
|
if (count($details) == 0) {
|
||||||
|
throw new Exception("details wajib diisi minimal 1 baris.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$periodeID = isset($para["periodeID"]) && (int) $para["periodeID"] > 0
|
||||||
|
? (int) $para["periodeID"]
|
||||||
|
: $this->getPeriodeIDByDate($date);
|
||||||
|
if ($periodeID <= 0) {
|
||||||
|
throw new Exception("Periode jurnal tidak ditemukan untuk tanggal {$date}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$regionalID = isset($para["regionalID"]) && (int) $para["regionalID"] > 0
|
||||||
|
? (int) $para["regionalID"]
|
||||||
|
: $this->getRegionalIDByBranchCode($branchCode);
|
||||||
|
if ($regionalID <= 0) {
|
||||||
|
throw new Exception("regionalID wajib diisi atau harus bisa diturunkan dari branchCode.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$branchCompanyID = isset($para["branchCompanyID"]) && (int) $para["branchCompanyID"] > 0
|
||||||
|
? (int) $para["branchCompanyID"]
|
||||||
|
: $this->getBranchCompanyIDByBranchCode($branchCode);
|
||||||
|
if ($branchCompanyID <= 0) {
|
||||||
|
throw new Exception("branchCompanyID wajib diisi atau harus bisa diturunkan dari branchCode.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$jurnalTypeID = isset($para["jurnalTypeID"]) && (int) $para["jurnalTypeID"] > 0
|
||||||
|
? (int) $para["jurnalTypeID"]
|
||||||
|
: $this->getJurnalTypeID(isset($para["jurnalTypeCode"]) && $para["jurnalTypeCode"] != "" ? $para["jurnalTypeCode"] : "PAYMENT");
|
||||||
|
if ($jurnalTypeID <= 0) {
|
||||||
|
throw new Exception("jurnalTypeID / jurnalTypeCode tidak valid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$userID = 0;
|
||||||
|
|
||||||
|
$result = $this->insertJournal(
|
||||||
|
$date,
|
||||||
|
$branchCode,
|
||||||
|
$title,
|
||||||
|
$description,
|
||||||
|
$details,
|
||||||
|
$periodeID,
|
||||||
|
$regionalID,
|
||||||
|
$branchCompanyID,
|
||||||
|
$jurnalTypeID,
|
||||||
|
$userID
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sys_ok($result);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GenerateJournalsFromContracts — Generate jurnal otomatis dari seluruh kontrak aset eligible.
|
||||||
|
*
|
||||||
|
* Fungsi ini mengintegrasikan data dari getEligiblePurchaseOrderAssetContracts()
|
||||||
|
* dengan proses pembuatan jurnal (insertJournal()) secara otomatis.
|
||||||
|
*
|
||||||
|
* Untuk setiap kontrak yang eligible, dibuat 1 jurnal dengan 2 baris transaksi:
|
||||||
|
* - Baris DEBIT : COA hutang cicilan (HutangCoaID dari fa_class) — mencatat hutang cicilan
|
||||||
|
* - Baris KREDIT : COA kas/bank/aset (ItemCoaID dari fa_class) — mencatat pembayaran cicilan
|
||||||
|
* Addon (jurnal_addon): menyimpan ID kontrak sebagai addonValue dan ItemID sebagai mItemID
|
||||||
|
*
|
||||||
|
* Parameter (POST JSON):
|
||||||
|
* - date : Tanggal jurnal (YYYY-MM-DD). Default: hari ini.
|
||||||
|
* - userID : ID user yang membuat jurnal.
|
||||||
|
* - dryRun : "Y" = simulasi tanpa simpan ke DB. Default: "N".
|
||||||
|
* - contractID : (opsional) Filter hanya 1 kontrak tertentu.
|
||||||
|
*
|
||||||
|
* Syarat kontrak dilewati (skipped):
|
||||||
|
* - branchCode kosong (data cabang belum lengkap)
|
||||||
|
* - COA hutang (HutangCoaID) tidak ditemukan di fa_class
|
||||||
|
* - COA bayar/aset (ItemCoaID) tidak ditemukan di fa_class
|
||||||
|
*
|
||||||
|
* @return JSON { tanggal, totalDibuat, totalDilewati, daftarDibuat[], daftarDilewati[] }
|
||||||
|
*/
|
||||||
|
public function GenerateJournalsFromContracts()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$date = isset($para["date"]) && $para["date"] != "" ? $para["date"] : date("Y-m-d");
|
||||||
|
if (!$this->isValidDate($date)) {
|
||||||
|
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$userID = 0;
|
||||||
|
$dryRun = isset($para["dryRun"]) && ($para["dryRun"] === true || $para["dryRun"] == "Y" || $para["dryRun"] == "1");
|
||||||
|
$filterContractID = isset($para["contractID"]) && (int) $para["contractID"] > 0
|
||||||
|
? (int) $para["contractID"]
|
||||||
|
: null;
|
||||||
|
|
||||||
|
$monthStart = date("Y-m-01", strtotime($date));
|
||||||
|
$monthEnd = date("Y-m-t", strtotime($date));
|
||||||
|
|
||||||
|
// Ambil semua kontrak yang eligible untuk periode bulan ini
|
||||||
|
$contracts = $this->getEligiblePurchaseOrderAssetContracts($monthStart, $monthEnd);
|
||||||
|
|
||||||
|
$dibuat = [];
|
||||||
|
$dilewati = [];
|
||||||
|
|
||||||
|
foreach ($contracts as $kontrak) {
|
||||||
|
$contractID = (int) $kontrak["PurchaseOrderAssetContractID"];
|
||||||
|
|
||||||
|
// Filter 1 kontrak jika diminta
|
||||||
|
if ($filterContractID !== null && $contractID !== $filterContractID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$branchCode = $kontrak["M_BranchCode"] ?? "";
|
||||||
|
$regionalID = (int) ($kontrak["M_BranchS_RegionalID"] ?? 0);
|
||||||
|
$branchCompanyID = (int) ($kontrak["M_BranchCompanyID"] ?? 0);
|
||||||
|
$coaHutangID = (int) ($kontrak["HutangCoaID"] ?? 0); // COA debit dari fa_class (Fa_ClassHutangCoaID)
|
||||||
|
$coaBayarID = (int) ($kontrak["ItemCoaID"] ?? 0); // COA kredit dari fa_class (Fa_ClassCoaID)
|
||||||
|
$jumlah = (float) $kontrak["PurchaseOrderAssetContractInstallmentPayAmount"];
|
||||||
|
$itemID = (int) ($kontrak["PurchaseOrderSummaryItemID"] ?? 0);
|
||||||
|
$namaKontrak = $kontrak["PurchaseOrderAssetContractName"] != ""
|
||||||
|
? $kontrak["PurchaseOrderAssetContractName"]
|
||||||
|
: "Kontrak ID {$contractID}";
|
||||||
|
$nomorPO = $kontrak["PurchaseOrderNumber"] ?? "";
|
||||||
|
$cicilanKe = ((int) $kontrak["PurchaseOrderAssetContractInstallmentPaid"]) + 1;
|
||||||
|
$totalCicilan = (int) $kontrak["PurchaseOrderAssetContractInstallmentNumber"];
|
||||||
|
$periode = date("Y-m", strtotime($date));
|
||||||
|
$invoiceNumber = $kontrak["SupplierInvoiceNumber"] ?? "";
|
||||||
|
$invoiceID = (int) ($kontrak["SupplierInvoiceID"] ?? 0);
|
||||||
|
|
||||||
|
// Validasi: branchCode harus ada
|
||||||
|
if ($branchCode == "") {
|
||||||
|
$dilewati[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"alasan" => "Kode cabang (branchCode) tidak ditemukan. Pastikan warehouse PO sudah terhubung ke data cabang."
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi: COA hutang harus ada (untuk sisi DEBIT)
|
||||||
|
if ($coaHutangID <= 0) {
|
||||||
|
$dilewati[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"branchCode" => $branchCode,
|
||||||
|
"alasan" => "COA hutang tidak ditemukan. Pastikan item PO memiliki Fa_Class dengan Fa_ClassHutangCoaID."
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi: COA bayar/aset harus ada (untuk sisi KREDIT)
|
||||||
|
if ($coaBayarID <= 0) {
|
||||||
|
$dilewati[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"branchCode" => $branchCode,
|
||||||
|
"alasan" => "COA bayar/aset tidak ditemukan. Pastikan item PO memiliki Fa_Class dengan Fa_ClassCoaID."
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode simulasi: catat tanpa simpan ke DB
|
||||||
|
if ($dryRun) {
|
||||||
|
$dibuat[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"branchCode" => $branchCode,
|
||||||
|
"namaKontrak" => $namaKontrak,
|
||||||
|
"invoiceNumber" => $invoiceNumber,
|
||||||
|
"jumlah" => $jumlah,
|
||||||
|
"coaHutangID" => $coaHutangID,
|
||||||
|
"coaBayarID" => $coaBayarID,
|
||||||
|
"keterangan" => "Mode simulasi (dryRun), data tidak disimpan."
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Susun title dan description jurnal
|
||||||
|
$title = "PI Cicilan Aset - {$invoiceNumber}";
|
||||||
|
$description = "Jurnal cicilan ke-{$cicilanKe} dari {$totalCicilan} | {$namaKontrak} | PO: {$nomorPO} | Periode {$periode}";
|
||||||
|
|
||||||
|
// Ambil periodeID dari tanggal
|
||||||
|
$periodeID = $this->getPeriodeIDByDate($date);
|
||||||
|
if ($periodeID <= 0) {
|
||||||
|
$dilewati[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"branchCode" => $branchCode,
|
||||||
|
"alasan" => "Periode jurnal tidak ditemukan untuk tanggal {$date}."
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambil jurnalTypeID untuk tipe PAYMENT
|
||||||
|
$jurnalTypeID = $this->getJurnalTypeID("PAYMENTINV");
|
||||||
|
if ($jurnalTypeID <= 0) {
|
||||||
|
$dilewati[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"branchCode" => $branchCode,
|
||||||
|
"alasan" => "Tipe jurnal PAYMENT tidak ditemukan di tabel jurnal_type."
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambil description detail dari database fa_class dengan fallback jika kosong
|
||||||
|
$descHutang = isset($kontrak["HutangCoaDesc"]) && $kontrak["HutangCoaDesc"] != ""
|
||||||
|
? $kontrak["HutangCoaDesc"]
|
||||||
|
: "Hutang cicilan aset - {$namaKontrak}";
|
||||||
|
$descBayar = isset($kontrak["ItemCoaDesc"]) && $kontrak["ItemCoaDesc"] != ""
|
||||||
|
? $kontrak["ItemCoaDesc"]
|
||||||
|
: "Pembayaran cicilan aset - {$namaKontrak}";
|
||||||
|
|
||||||
|
// Susun 2 baris detail jurnal:
|
||||||
|
// Baris 1 — DEBIT : hutang cicilan aset (COA dari fa_class)
|
||||||
|
// Baris 2 — KREDIT : pembayaran cicilan (COA kas/bank dari parameter)
|
||||||
|
$details = [
|
||||||
|
[
|
||||||
|
"coaID" => $coaHutangID,
|
||||||
|
"description" => $descHutang,
|
||||||
|
"debit" => $jumlah,
|
||||||
|
"credit" => 0,
|
||||||
|
"addonValue" => $invoiceNumber,
|
||||||
|
"mItemID" => $itemID,
|
||||||
|
"addonCode" => "PIINSTALMENT"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"coaID" => $coaBayarID,
|
||||||
|
"description" => $descBayar,
|
||||||
|
"debit" => 0,
|
||||||
|
"credit" => $jumlah,
|
||||||
|
"addonValue" => $invoiceNumber,
|
||||||
|
"mItemID" => $itemID,
|
||||||
|
"addonCode" => "PIINSTALMENT"
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
// Panggil insertJournal() untuk simpan ke DB
|
||||||
|
$result = $this->insertJournal(
|
||||||
|
$date,
|
||||||
|
$branchCode,
|
||||||
|
$title,
|
||||||
|
$description,
|
||||||
|
$details,
|
||||||
|
$periodeID,
|
||||||
|
$regionalID,
|
||||||
|
$branchCompanyID,
|
||||||
|
$jurnalTypeID,
|
||||||
|
$userID
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
$dilewati[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"branchCode" => $branchCode,
|
||||||
|
"alasan" => "Gagal menyimpan jurnal ke database."
|
||||||
|
];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dibuat[] = [
|
||||||
|
"kontrakID" => $contractID,
|
||||||
|
"branchCode" => $branchCode,
|
||||||
|
"namaKontrak" => $namaKontrak,
|
||||||
|
"jurnalID" => $result["jurnalID"],
|
||||||
|
"jurnalNo" => $result["jurnalNo"],
|
||||||
|
"jumlah" => $jumlah
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sys_ok([
|
||||||
|
"tanggal" => $date,
|
||||||
|
"periodeAwal" => $monthStart,
|
||||||
|
"periodeAkhir" => $monthEnd,
|
||||||
|
"totalDibuat" => count($dibuat),
|
||||||
|
"totalDilewati" => count($dilewati),
|
||||||
|
"daftarDibuat" => $dibuat,
|
||||||
|
"daftarDilewati" => $dilewati
|
||||||
|
]);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ListEligiblePurchaseOrderAssetContracts — Menampilkan daftar kontrak aset
|
||||||
|
* yang memenuhi syarat untuk dibuatkan jurnal PI cicilan pada periode tertentu.
|
||||||
|
*
|
||||||
|
* Syarat kontrak eligible:
|
||||||
|
* - Kontrak aktif dan berstatus "belum lunas"
|
||||||
|
* - Nilai cicilan > 0
|
||||||
|
* - Jumlah cicilan terbayar < total cicilan
|
||||||
|
* - Tanggal kontrak masuk dalam rentang startDate–endDate
|
||||||
|
* - PO sudah berstatus Approved
|
||||||
|
* - Barang sudah diterima (receive_order_po sudah confirmed)
|
||||||
|
*
|
||||||
|
* Endpoint ini digunakan untuk preview/verifikasi sebelum proses generate jurnal
|
||||||
|
* dijalankan secara massal oleh CRON.
|
||||||
|
*
|
||||||
|
* Parameter (GET/POST):
|
||||||
|
* - startDate : Awal periode (YYYY-MM-DD). Default: tanggal 1 bulan ini.
|
||||||
|
* - endDate : Akhir periode (YYYY-MM-DD). Default: tanggal akhir bulan ini.
|
||||||
|
*
|
||||||
|
* @return JSON { startDate, endDate, total, records[] }
|
||||||
|
*/
|
||||||
|
public function ListEligiblePurchaseOrderAssetContracts()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$startDate = isset($para["startDate"]) && $para["startDate"] != ""
|
||||||
|
? $para["startDate"]
|
||||||
|
: date("Y-m-01");
|
||||||
|
$endDate = isset($para["endDate"]) && $para["endDate"] != ""
|
||||||
|
? $para["endDate"]
|
||||||
|
: date("Y-m-t");
|
||||||
|
|
||||||
|
if (!$this->isValidDate($startDate) || !$this->isValidDate($endDate)) {
|
||||||
|
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strtotime($startDate) > strtotime($endDate)) {
|
||||||
|
throw new Exception("startDate tidak boleh lebih besar dari endDate");
|
||||||
|
}
|
||||||
|
|
||||||
|
$records = $this->getEligiblePurchaseOrderAssetContracts($startDate, $endDate);
|
||||||
|
|
||||||
|
$this->sys_ok([
|
||||||
|
"startDate" => $startDate,
|
||||||
|
"endDate" => $endDate,
|
||||||
|
"total" => count($records),
|
||||||
|
"records" => $records
|
||||||
|
]);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// FUNGSI PRIVATE / HELPER
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insertJournal — Menyimpan 1 jurnal lengkap ke database (header + tx + addon).
|
||||||
|
*
|
||||||
|
* Fungsi internal yang dipanggil oleh CreateJournal() dan GenerateJournalsFromContracts().
|
||||||
|
* Mengelola transaksi DB secara penuh (begin → commit/rollback).
|
||||||
|
*
|
||||||
|
* Alur:
|
||||||
|
* 1. Validasi balance debit == kredit
|
||||||
|
* 2. Generate nomor jurnal via fn_numbering('J')
|
||||||
|
* 3. INSERT header ke tabel `jurnal`
|
||||||
|
* 4. INSERT baris transaksi ke `jurnal_tx` (per detail)
|
||||||
|
* 5. INSERT addon ke `jurnal_addon` (jika addonValue atau mItemID ada)
|
||||||
|
*
|
||||||
|
* @param string $date Tanggal jurnal (YYYY-MM-DD)
|
||||||
|
* @param string $branchCode Kode cabang
|
||||||
|
* @param string $title Judul jurnal
|
||||||
|
* @param string $description Keterangan jurnal
|
||||||
|
* @param array $details Baris transaksi [ coaID, description, debit, credit, addonValue?, mItemID?, addonCode? ]
|
||||||
|
* @param int $periodeID ID periode akuntansi
|
||||||
|
* @param int $regionalID ID regional
|
||||||
|
* @param int $branchCompanyID ID branch company
|
||||||
|
* @param int $jurnalTypeID ID tipe jurnal
|
||||||
|
* @param int $userID ID user pembuat jurnal
|
||||||
|
*
|
||||||
|
* @return array|false Array { jurnalID, jurnalNo, detailCount, addonCount }, atau false jika gagal
|
||||||
|
*/
|
||||||
|
private function insertJournal($date, $branchCode, $title, $description, $details, $periodeID, $regionalID, $branchCompanyID, $jurnalTypeID, $userID)
|
||||||
|
{
|
||||||
|
// Validasi balance sebelum menyimpan
|
||||||
|
$totalDebit = 0;
|
||||||
|
$totalCredit = 0;
|
||||||
|
foreach ($details as $idx => $detail) {
|
||||||
|
$debit = isset($detail["debit"]) ? (float) $detail["debit"] : 0;
|
||||||
|
$credit = isset($detail["credit"]) ? (float) $detail["credit"] : 0;
|
||||||
|
if ($debit < 0 || $credit < 0) {
|
||||||
|
$this->sys_error("Nilai debit/credit tidak boleh negatif pada detail ke-" . ($idx + 1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$totalDebit += $debit;
|
||||||
|
$totalCredit += $credit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (round($totalDebit, 2) !== round($totalCredit, 2)) {
|
||||||
|
$this->sys_error("Total debit dan credit harus sama. Debit={$totalDebit}, Credit={$totalCredit}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$jurnalNo = $this->generateJournalNumber();
|
||||||
|
if ($jurnalNo === false || $jurnalNo == "") {
|
||||||
|
$this->sys_error("Gagal generate nomor jurnal.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// INSERT header jurnal ke tabel `jurnal`
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
$sqlHeader = "INSERT INTO jurnal (
|
||||||
|
jurnalM_BranchCompanyID,
|
||||||
|
JurnalS_RegionalID,
|
||||||
|
jurnalM_BranchCode,
|
||||||
|
jurnalperiodeID,
|
||||||
|
jurnalNo,
|
||||||
|
jurnalTitle,
|
||||||
|
jurnalDescription,
|
||||||
|
jurnalDate,
|
||||||
|
jurnalJurnalTypeID,
|
||||||
|
jurnalCreated,
|
||||||
|
jurnalM_UserID
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,NOW(),?)";
|
||||||
|
|
||||||
|
$qryHeader = $this->db->query($sqlHeader, [
|
||||||
|
$branchCompanyID,
|
||||||
|
$regionalID,
|
||||||
|
$branchCode,
|
||||||
|
$periodeID,
|
||||||
|
$jurnalNo,
|
||||||
|
$title,
|
||||||
|
$description,
|
||||||
|
$date,
|
||||||
|
$jurnalTypeID,
|
||||||
|
$userID
|
||||||
|
]);
|
||||||
|
if (!$qryHeader) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Gagal insert jurnal header.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$jurnalID = $this->db->insert_id();
|
||||||
|
$createdAddonCount = 0;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// INSERT baris transaksi ke tabel `jurnal_tx` (per baris cicilan)
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
foreach ($details as $idx => $detail) {
|
||||||
|
$coaID = isset($detail["coaID"]) ? (int) $detail["coaID"] : 0;
|
||||||
|
$descriptionTx = isset($detail["description"]) ? trim($detail["description"]) : "";
|
||||||
|
$debit = isset($detail["debit"]) ? (float) $detail["debit"] : 0;
|
||||||
|
$credit = isset($detail["credit"]) ? (float) $detail["credit"] : 0;
|
||||||
|
|
||||||
|
if ($coaID <= 0) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("coaID wajib diisi pada detail ke-" . ($idx + 1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sisi debit = hutang cicilan (COA hutang aset dari fa_class)
|
||||||
|
// Sisi kredit = pembayaran cicilan (COA kas/bank)
|
||||||
|
$sqlTx = "INSERT INTO jurnal_tx (
|
||||||
|
jurnalTxJurnalID,
|
||||||
|
jurnalTxCoaID,
|
||||||
|
jurnalTxDescription,
|
||||||
|
jurnalTxDebit,
|
||||||
|
jurnalTxCredit,
|
||||||
|
jurnalTxCreated,
|
||||||
|
jurnalTxM_UserID
|
||||||
|
) VALUES (?,?,?,?,?,NOW(),?)";
|
||||||
|
|
||||||
|
$qryTx = $this->db->query($sqlTx, [
|
||||||
|
$jurnalID,
|
||||||
|
$coaID,
|
||||||
|
$descriptionTx,
|
||||||
|
$debit,
|
||||||
|
$credit,
|
||||||
|
$userID
|
||||||
|
]);
|
||||||
|
if (!$qryTx) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Gagal insert jurnal_tx pada detail ke-" . ($idx + 1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$jurnalTxID = $this->db->insert_id();
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// INSERT addon ke `jurnal_addon` (jika addonValue atau mItemID ada)
|
||||||
|
// addonValue = ID kontrak aset (untuk tracing)
|
||||||
|
// mItemID = ID item aset dari purchase_order_summary
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
$addonValue = isset($detail["addonValue"]) ? trim($detail["addonValue"]) : "";
|
||||||
|
$mItemID = isset($detail["mItemID"]) ? (int) $detail["mItemID"] : 0;
|
||||||
|
$addonCode = isset($detail["addonCode"]) && $detail["addonCode"] != "" ? trim($detail["addonCode"]) : "PIINSTALMENT";
|
||||||
|
|
||||||
|
if ($addonValue != "" || $mItemID > 0) {
|
||||||
|
$sqlAddon = "INSERT INTO jurnal_addon (
|
||||||
|
jurnalAddOnJurnalID,
|
||||||
|
jurnalAddOnJurnalTxID,
|
||||||
|
jurnalAddOnCode,
|
||||||
|
jurnalAddOnValue,
|
||||||
|
jurnalAddOnM_ItemID,
|
||||||
|
jurnalAddOnCreated,
|
||||||
|
jurnalAddOnCreatedUserID
|
||||||
|
) VALUES (?,?,?,?,?,NOW(),?)";
|
||||||
|
|
||||||
|
$qryAddon = $this->db->query($sqlAddon, [
|
||||||
|
$jurnalID,
|
||||||
|
$jurnalTxID,
|
||||||
|
$addonCode,
|
||||||
|
$addonValue,
|
||||||
|
$mItemID > 0 ? $mItemID : null,
|
||||||
|
$userID
|
||||||
|
]);
|
||||||
|
if (!$qryAddon) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Gagal insert jurnal_addon pada detail ke-" . ($idx + 1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$createdAddonCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->db->trans_status() === false) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Transaksi jurnal gagal.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
|
||||||
|
return [
|
||||||
|
"jurnalID" => $jurnalID,
|
||||||
|
"jurnalNo" => $jurnalNo,
|
||||||
|
"detailCount" => count($details),
|
||||||
|
"addonCount" => $createdAddonCount
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generateJournalNumber — Generate nomor jurnal otomatis.
|
||||||
|
*
|
||||||
|
* Memanggil stored function MySQL fn_numbering('J') untuk mendapatkan
|
||||||
|
* nomor jurnal berikutnya sesuai urutan penomoran yang berlaku.
|
||||||
|
*
|
||||||
|
* @return string|false Nomor jurnal (misal: "J/2025/07/0001"), atau false jika gagal.
|
||||||
|
*/
|
||||||
|
private function generateJournalNumber()
|
||||||
|
{
|
||||||
|
$qry = $this->db->query("SELECT fn_numbering('J') AS JNumber");
|
||||||
|
if (!$qry || $qry->num_rows() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $qry->row_array()["JNumber"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getPeriodeIDByDate — Ambil ID periode akuntansi berdasarkan tanggal transaksi.
|
||||||
|
*
|
||||||
|
* Periode diambil dari tabel `periode` yang aktif dan mencakup tanggal yang diberikan.
|
||||||
|
* Digunakan untuk mengisi field jurnalperiodeID pada header jurnal.
|
||||||
|
*
|
||||||
|
* @param string $date Tanggal transaksi (format YYYY-MM-DD)
|
||||||
|
* @return int periodeID yang sesuai, atau 0 jika tidak ditemukan
|
||||||
|
*/
|
||||||
|
private function getPeriodeIDByDate($date)
|
||||||
|
{
|
||||||
|
$sql = "SELECT periodeID
|
||||||
|
FROM periode
|
||||||
|
WHERE periodeIsActive = 'Y'
|
||||||
|
AND DATE(?) BETWEEN periodeStartDate AND periodeEndDate
|
||||||
|
LIMIT 1";
|
||||||
|
$qry = $this->db->query($sql, [$date]);
|
||||||
|
if (!$qry || $qry->num_rows() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int) $qry->row_array()["periodeID"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getBranchCompanyIDByBranchCode — Ambil ID branch company berdasarkan kode cabang.
|
||||||
|
*
|
||||||
|
* Data diambil dari tabel `m_branch_companydetail` yang aktif.
|
||||||
|
* Digunakan untuk mengisi field jurnalM_BranchCompanyID pada header jurnal.
|
||||||
|
*
|
||||||
|
* @param string $branchCode Kode cabang (misal: "JKT-01")
|
||||||
|
* @return int branchCompanyID yang sesuai, atau 0 jika tidak ditemukan
|
||||||
|
*/
|
||||||
|
private function getBranchCompanyIDByBranchCode($branchCode)
|
||||||
|
{
|
||||||
|
$sql = "SELECT M_BranchCompanyDetailM_BranchCompanyID AS branchCompanyID
|
||||||
|
FROM m_branch_companydetail
|
||||||
|
WHERE M_BranchCompanyDetailM_BranchCode = ?
|
||||||
|
AND M_BranchCompanyDetailIsActive = 'Y'
|
||||||
|
LIMIT 1";
|
||||||
|
$qry = $this->db->query($sql, [$branchCode]);
|
||||||
|
if (!$qry || $qry->num_rows() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int) $qry->row_array()["branchCompanyID"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getRegionalIDByBranchCode — Ambil ID regional berdasarkan kode cabang.
|
||||||
|
*
|
||||||
|
* Data diambil dari tabel `m_branch` yang aktif.
|
||||||
|
* Digunakan untuk mengisi field JurnalS_RegionalID pada header jurnal.
|
||||||
|
*
|
||||||
|
* @param string $branchCode Kode cabang (misal: "JKT-01")
|
||||||
|
* @return int regionalID yang sesuai, atau 0 jika tidak ditemukan
|
||||||
|
*/
|
||||||
|
private function getRegionalIDByBranchCode($branchCode)
|
||||||
|
{
|
||||||
|
$sql = "SELECT M_BranchS_RegionalID AS regionalID
|
||||||
|
FROM m_branch
|
||||||
|
WHERE M_BranchCode = ?
|
||||||
|
AND M_BranchIsActive = 'Y'
|
||||||
|
LIMIT 1";
|
||||||
|
$qry = $this->db->query($sql, [$branchCode]);
|
||||||
|
if (!$qry || $qry->num_rows() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int) $qry->row_array()["regionalID"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getJurnalTypeID — Ambil ID tipe jurnal berdasarkan kode tipe.
|
||||||
|
*
|
||||||
|
* Data diambil dari tabel `jurnal_type` yang aktif.
|
||||||
|
* Untuk PI cicilan order aset, kode yang digunakan adalah "PAYMENT".
|
||||||
|
*
|
||||||
|
* @param string $jurnalTypeCode Kode tipe jurnal (misal: "PAYMENT")
|
||||||
|
* @return int JurnalTypeID yang sesuai, atau 0 jika tidak ditemukan
|
||||||
|
*/
|
||||||
|
private function getJurnalTypeID($jurnalTypeCode)
|
||||||
|
{
|
||||||
|
$sql = "SELECT JurnalTypeID
|
||||||
|
FROM jurnal_type
|
||||||
|
WHERE JurnalTypeCode = ?
|
||||||
|
AND JurnalTypeIsActive = 'Y'
|
||||||
|
LIMIT 1";
|
||||||
|
$qry = $this->db->query($sql, [$jurnalTypeCode]);
|
||||||
|
if (!$qry || $qry->num_rows() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int) $qry->row_array()["JurnalTypeID"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getEligiblePurchaseOrderAssetContracts — Ambil kontrak aset yang layak dibuatkan jurnal.
|
||||||
|
*
|
||||||
|
* Query ini mengambil semua kontrak dari `purchase_order_asset_contract` yang memenuhi
|
||||||
|
* syarat berikut:
|
||||||
|
* - Kontrak aktif, status "belum lunas", nilai cicilan > 0
|
||||||
|
* - Cicilan terbayar masih kurang dari total cicilan
|
||||||
|
* - Tanggal kontrak masuk dalam rentang periode yang diberikan
|
||||||
|
* - Tanggal jatuh tempo cicilan sudah lewat atau sama dengan hari ini
|
||||||
|
* - PO sudah Approved dan aktif
|
||||||
|
* - Barang sudah diterima dan receive order sudah confirmed
|
||||||
|
*
|
||||||
|
* Data yang dikembalikan mencakup:
|
||||||
|
* - Detail kontrak (ID, nama, tanggal, nilai cicilan)
|
||||||
|
* - Data PO (nomor PO, supplier, payment term, warehouse)
|
||||||
|
* - Data cabang (kode cabang, nama, regionalID, branchCompanyID)
|
||||||
|
* - Data item PO pertama (sebagai referensi baris jurnal)
|
||||||
|
*
|
||||||
|
* @param string $startDate Awal periode filter (YYYY-MM-DD)
|
||||||
|
* @param string $endDate Akhir periode filter (YYYY-MM-DD)
|
||||||
|
* @return array Array of row kontrak yang eligible
|
||||||
|
*/
|
||||||
|
private function getEligiblePurchaseOrderAssetContracts($startDate, $endDate)
|
||||||
|
{
|
||||||
|
$sql = "SELECT
|
||||||
|
c.PurchaseOrderAssetContractID,
|
||||||
|
si.SupplierInvoiceID,
|
||||||
|
si.SupplierInvoiceNumber,
|
||||||
|
c.PurchaseOrderAssetContractPurchaseOrderID,
|
||||||
|
c.PurchaseOrderAssetContractName,
|
||||||
|
c.PurchaseOrderAssetContractStartDate,
|
||||||
|
c.PurchaseOrderAssetContractEndDate,
|
||||||
|
c.PurchaseOrderAssetContractInstallmentNumber,
|
||||||
|
c.PurchaseOrderAssetContractInstallmentPaid,
|
||||||
|
c.PurchaseOrderAssetContractInstallmentDate,
|
||||||
|
c.PurchaseOrderAssetContractInstallmentPayAmount,
|
||||||
|
c.PurchaseOrderAssetContractReceiveOrderPoID,
|
||||||
|
po.PurchaseOrderID,
|
||||||
|
po.PurchaseOrderNumber,
|
||||||
|
po.PurchaseOrderSupplierID,
|
||||||
|
po.PurchaseOrderPaymentTerm,
|
||||||
|
po.PurchaseOrderWarehouseType,
|
||||||
|
po.PurchaseOrderWarehouseID,
|
||||||
|
wh.WarehouseCode,
|
||||||
|
wh.WarehouseName,
|
||||||
|
wh.WarehouseType,
|
||||||
|
wh.WarehouseS_RegionalID AS WarehouseS_RegionalID,
|
||||||
|
wh.WarehouseM_BranchID AS WarehouseM_BranchID,
|
||||||
|
ro.ReceiveOrderPoID,
|
||||||
|
ro.ReceiveOrderPoConfirmed,
|
||||||
|
mi.M_ItemID AS ItemID,
|
||||||
|
mi.M_ItemCode AS ItemCode,
|
||||||
|
mi.M_ItemDesc AS ItemDesc,
|
||||||
|
mi.M_ItemFa_ClassID,
|
||||||
|
fc.Fa_ClassID AS ItemFaClassID,
|
||||||
|
fc.Fa_ClassName AS ItemFaClassName,
|
||||||
|
coa_bayar.coaID AS ItemCoaID,
|
||||||
|
coa_bayar.coaAccountNo AS ItemCoaAccountNo,
|
||||||
|
coa_bayar.coaDescription AS ItemCoaDesc,
|
||||||
|
coa_hutang.coaID AS HutangCoaID,
|
||||||
|
coa_hutang.coaAccountNo AS HutangCoaAccountNo,
|
||||||
|
coa_hutang.coaDescription AS HutangCoaDesc,
|
||||||
|
m_branch.M_BranchCode,
|
||||||
|
m_branch.M_BranchName,
|
||||||
|
m_branch.M_BranchS_RegionalID,
|
||||||
|
m_branch_companydetail.M_BranchCompanyDetailM_BranchCompanyID AS M_BranchCompanyID,
|
||||||
|
ps.PurchaseOrderSummaryID,
|
||||||
|
ps.PurchaseOrderSummaryItemID,
|
||||||
|
ps.PurchaseOrderSummaryItemUnitID
|
||||||
|
FROM purchase_order_asset_contract c
|
||||||
|
|
||||||
|
-- Pastikan PO sudah Approved dan aktif
|
||||||
|
JOIN purchase_order po
|
||||||
|
ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID
|
||||||
|
AND po.PurchaseOrderIsActive = 'Y'
|
||||||
|
AND po.PurchaseOrderStatus = 'Approved'
|
||||||
|
|
||||||
|
-- Data warehouse/gudang tujuan PO
|
||||||
|
LEFT JOIN warehouse wh
|
||||||
|
ON wh.WarehouseID = po.PurchaseOrderWarehouseID
|
||||||
|
|
||||||
|
-- Ambil 1 item PO pertama sebagai referensi baris jurnal
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT ps0.*
|
||||||
|
FROM purchase_order_summary ps0
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
PurchaseOrderSummaryPurchaseOrderID,
|
||||||
|
MIN(PurchaseOrderSummaryID) AS PurchaseOrderSummaryID
|
||||||
|
FROM purchase_order_summary
|
||||||
|
WHERE PurchaseOrderSummaryIsActive = 'Y'
|
||||||
|
GROUP BY PurchaseOrderSummaryPurchaseOrderID
|
||||||
|
) psx
|
||||||
|
ON psx.PurchaseOrderSummaryID = ps0.PurchaseOrderSummaryID
|
||||||
|
) ps
|
||||||
|
ON ps.PurchaseOrderSummaryPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
|
||||||
|
-- Hubungkan dengan detail supplier_invoice_detail terlebih dahulu
|
||||||
|
JOIN supplier_invoice_detail sid
|
||||||
|
ON sid.SupplierInvoiceDetailPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
AND sid.SupplierInvoiceDetailPurchaseOrderSummaryID = ps.PurchaseOrderSummaryID
|
||||||
|
AND sid.SupplierInvoiceDetailIsActive = 'Y'
|
||||||
|
|
||||||
|
-- Baru hubungkan ke header supplier_invoice untuk mengambil nomor invoice
|
||||||
|
JOIN supplier_invoice si
|
||||||
|
ON si.SupplierInvoiceID = sid.SupplierInvoiceDetailSupplierInvoiceID
|
||||||
|
AND si.SupplierInvoiceDate >= DATE(?)
|
||||||
|
AND si.SupplierInvoiceDate <= DATE(?)
|
||||||
|
AND si.SupplierInvoiceIsActive = 'Y'
|
||||||
|
|
||||||
|
-- Pastikan barang sudah diterima (receive order confirmed)
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
rd.ReceiveOrderPoDetailPurchaseOrderID,
|
||||||
|
MIN(ro0.ReceiveOrderPoID) AS ReceiveOrderPoID,
|
||||||
|
MAX(ro0.ReceiveOrderPoConfirmed) AS ReceiveOrderPoConfirmed
|
||||||
|
FROM receive_order_po ro0
|
||||||
|
JOIN receive_order_po_detail rd
|
||||||
|
ON rd.ReceiveOrderPoDetailReceiveOrderPoID = ro0.ReceiveOrderPoID
|
||||||
|
AND rd.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
WHERE ro0.ReceiveOrderPoIsActive = 'Y'
|
||||||
|
AND ro0.ReceiveOrderPoConfirmed = 'Y'
|
||||||
|
GROUP BY rd.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
) ro
|
||||||
|
ON ro.ReceiveOrderPoDetailPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
|
||||||
|
-- Data cabang dari warehouse
|
||||||
|
LEFT JOIN m_branch
|
||||||
|
ON m_branch.M_BranchID = wh.WarehouseM_BranchID
|
||||||
|
AND m_branch.M_BranchIsActive = 'Y'
|
||||||
|
|
||||||
|
-- Data branch company untuk header jurnal
|
||||||
|
LEFT JOIN m_branch_companydetail
|
||||||
|
ON m_branch_companydetail.M_BranchCompanyDetailM_BranchCode = m_branch.M_BranchCode
|
||||||
|
AND m_branch_companydetail.M_BranchCompanyDetailIsActive = 'Y'
|
||||||
|
|
||||||
|
-- COA jurnal diambil dari item -> fa_class
|
||||||
|
LEFT JOIN m_item mi
|
||||||
|
ON mi.M_ItemID = ps.PurchaseOrderSummaryItemID
|
||||||
|
AND mi.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN fa_class fc
|
||||||
|
ON fc.Fa_ClassID = mi.M_ItemFa_ClassID
|
||||||
|
AND fc.Fa_ClassIsActive = 'Y'
|
||||||
|
|
||||||
|
-- Join langsung ke tabel coa untuk memastikan kevalidan akun dan deskripsi
|
||||||
|
LEFT JOIN coa coa_hutang
|
||||||
|
ON coa_hutang.coaID = fc.Fa_ClassHutangCoaID
|
||||||
|
AND coa_hutang.coaIsActive = 'Y'
|
||||||
|
LEFT JOIN coa coa_bayar
|
||||||
|
ON coa_bayar.coaID = fc.Fa_ClassCoaID
|
||||||
|
AND coa_bayar.coaIsActive = 'Y'
|
||||||
|
|
||||||
|
WHERE c.PurchaseOrderAssetContractIsActive = 'Y'
|
||||||
|
AND c.PurchaseOrderAssetContractStatus = 'belum lunas'
|
||||||
|
-- Hanya kontrak yang ada nilai cicilannya
|
||||||
|
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0
|
||||||
|
-- Hanya kontrak yang belum selesai seluruh cicilannya
|
||||||
|
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0) < IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0)
|
||||||
|
-- Kontrak sudah mulai sebelum atau pada akhir periode
|
||||||
|
AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?)
|
||||||
|
-- Kontrak belum berakhir (atau tidak ada tanggal akhir)
|
||||||
|
AND (
|
||||||
|
c.PurchaseOrderAssetContractEndDate IS NULL
|
||||||
|
OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?)
|
||||||
|
)
|
||||||
|
-- Tanggal jatuh tempo cicilan sudah tiba
|
||||||
|
AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ?
|
||||||
|
-- Pastikan belum pernah dibuatkan jurnal untuk invoice cicilan ini
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM jurnal_addon ja
|
||||||
|
JOIN jurnal j ON j.jurnalID = ja.jurnalAddOnJurnalID
|
||||||
|
WHERE ja.jurnalAddOnCode = 'PIINSTALMENT'
|
||||||
|
AND ja.jurnalAddOnValue = si.SupplierInvoiceNumber
|
||||||
|
)
|
||||||
|
ORDER BY c.PurchaseOrderAssetContractID ASC";
|
||||||
|
|
||||||
|
$qry = $this->db->query($sql, [
|
||||||
|
$startDate,
|
||||||
|
$endDate,
|
||||||
|
$endDate,
|
||||||
|
$startDate,
|
||||||
|
(int) date("d", strtotime($endDate))
|
||||||
|
]);
|
||||||
|
if (!$qry) {
|
||||||
|
$this->sys_error_db("Gagal mengambil data purchase_order_asset_contract.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qry->result_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isValidDate — Validasi format tanggal YYYY-MM-DD.
|
||||||
|
*
|
||||||
|
* @param string $tanggal String tanggal yang akan divalidasi
|
||||||
|
* @return bool true jika format valid, false jika tidak
|
||||||
|
*/
|
||||||
|
private function isValidDate($tanggal)
|
||||||
|
{
|
||||||
|
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
||||||
|
return $d && $d->format("Y-m-d") === $tanggal;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# FILE : PurchaseInvoiceInstallment.http
|
||||||
|
# MODUL : Scheduler — Generate Supplier Installment Cicilan Aset
|
||||||
|
# ============================================================
|
||||||
|
#
|
||||||
|
# DESKRIPSI
|
||||||
|
# ---------
|
||||||
|
# File ini berisi HTTP request untuk menguji endpoint scheduler
|
||||||
|
# yang secara otomatis membuat baris cicilan ke tabel
|
||||||
|
# supplier_installment setiap bulan.
|
||||||
|
#
|
||||||
|
# CARA PAKAI
|
||||||
|
# ----------
|
||||||
|
# 1. Gunakan ekstensi "REST Client" di VS Code (humao.rest-client)
|
||||||
|
# atau tool sejenis (IntelliJ HTTP Client, Postman, dll).
|
||||||
|
# 2. Ganti nilai @host sesuai environment.
|
||||||
|
# 3. Klik "Send Request" di atas tiap blok ###
|
||||||
|
#
|
||||||
|
# ALUR
|
||||||
|
# ----
|
||||||
|
# [1] GenerateMonthlyInvoices → Jalankan proses generate installment
|
||||||
|
#
|
||||||
|
# CATATAN
|
||||||
|
# -------
|
||||||
|
# - Default periode: bulan berjalan (tanggal 1 s/d akhir bulan)
|
||||||
|
# - Aman dijalankan ulang — dedup berdasarkan PO + bulan mencegah
|
||||||
|
# duplikasi
|
||||||
|
# - Tidak membuat jurnal — jurnal dibuat saat pembayaran cashier
|
||||||
|
# - Tidak update kontrak — InstallmentPaid diupdate saat pembayaran
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
@host = https://accone.aplikasi.web.id/one-api
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# [1] GENERATE INSTALLMENT BULANAN (MAIN ENDPOINT)
|
||||||
|
# ============================================================
|
||||||
|
# Satu request ini akan:
|
||||||
|
# Step 1: Validasi kontrak (aktif, belum lunas, dalam rentang)
|
||||||
|
# Step 2: Validasi PO (Approved, Active)
|
||||||
|
# Step 3: Validasi RO (Confirmed, Active)
|
||||||
|
# Step 4: Validasi parent invoice (IsInstallment = 'Y')
|
||||||
|
# Step 5: Cek dedup (belum ada installment bulan ini)
|
||||||
|
# Step 6: INSERT ke supplier_installment (Status = 'Pending')
|
||||||
|
#
|
||||||
|
# Response:
|
||||||
|
# - totalEligible : jumlah kontrak lolos validasi
|
||||||
|
# - totalInserted : jumlah baris berhasil diinsert
|
||||||
|
# - created[] : detail tiap installment yang dibuat
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
### [1] Generate installment untuk periode tertentu
|
||||||
|
POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"startDate": "2026-07-01",
|
||||||
|
"endDate": "2026-07-31"
|
||||||
|
}
|
||||||
|
|
||||||
|
### [1a] Generate installment bulan berjalan (tanpa parameter)
|
||||||
|
POST {{host}}/mockup/scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PurchaseInvoiceInstallment
|
||||||
|
*
|
||||||
|
* CRON scheduler untuk membuat baris cicilan otomatis ke tabel supplier_installment
|
||||||
|
* setiap bulan berdasarkan kontrak aset yang aktif dan belum lunas.
|
||||||
|
*
|
||||||
|
* Endpoint:
|
||||||
|
* POST /scheduler/PurchaseInvoiceInstallment/GenerateMonthlyInvoices
|
||||||
|
*/
|
||||||
|
class PurchaseInvoiceInstallment extends MY_Controller
|
||||||
|
{
|
||||||
|
var $db;
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Purchase Invoice Installment — Auto Generate Installment Cicilan Aset";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GenerateMonthlyInvoices — Step 6
|
||||||
|
*
|
||||||
|
* Creates supplier_installment rows for all eligible contracts this month.
|
||||||
|
* No journal is created here — that happens at cashier payment time.
|
||||||
|
* Contract InstallmentPaid is NOT updated here — that happens at payment time.
|
||||||
|
*
|
||||||
|
* Called by CRON daily at 1:00 AM.
|
||||||
|
* Defaults to current month if no startDate/endDate provided.
|
||||||
|
*/
|
||||||
|
public function GenerateMonthlyInvoices()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$userID = !empty($this->sys_user["M_UserID"])
|
||||||
|
? (int) $this->sys_user["M_UserID"]
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
$startDate = !empty($para["startDate"])
|
||||||
|
? $para["startDate"]
|
||||||
|
: date("Y-m-01");
|
||||||
|
|
||||||
|
$endDate = !empty($para["endDate"])
|
||||||
|
? $para["endDate"]
|
||||||
|
: date("Y-m-t");
|
||||||
|
|
||||||
|
if (!$this->isValidDate($startDate) || !$this->isValidDate($endDate)) {
|
||||||
|
throw new Exception("Format tanggal tidak valid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strtotime($startDate) > strtotime($endDate)) {
|
||||||
|
throw new Exception("startDate > endDate.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Steps 1–5: Get eligible contracts ────────────────────
|
||||||
|
$eligible = $this->getEligibleInstallments($startDate, $endDate);
|
||||||
|
|
||||||
|
$created = [];
|
||||||
|
$inserted = 0;
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
foreach ($eligible as $row) {
|
||||||
|
|
||||||
|
$amount = (float) $row["PurchaseOrderAssetContractInstallmentPayAmount"];
|
||||||
|
$dayOfMonth = (int) ($row["PurchaseOrderAssetContractInstallmentDate"] ?? 1);
|
||||||
|
$lastDay = (int) date("t", strtotime($endDate));
|
||||||
|
$dayOfMonth = min($dayOfMonth, $lastDay);
|
||||||
|
$installDate = date("Y-m", strtotime($endDate)) . "-" . str_pad($dayOfMonth, 2, "0", STR_PAD_LEFT);
|
||||||
|
$dueDate = date("Y-m-d", strtotime($installDate . " +7 days"));
|
||||||
|
$createdBy = (int) ($row["PurchaseOrderAssetContractCreatedUserID"] ?? $userID);
|
||||||
|
|
||||||
|
// ── Step 6: INSERT supplier_installment ──────────────
|
||||||
|
$sql = "INSERT INTO supplier_installment (
|
||||||
|
SupplierInstallmentPurchaseOrderID,
|
||||||
|
SupplierInstallmentSupplierID,
|
||||||
|
SupplierInstallmentSupplierInvoiceID,
|
||||||
|
SupplierInstallmentAmount,
|
||||||
|
SupplierInstallmentDate,
|
||||||
|
SupplierInstallmentDueDate,
|
||||||
|
SupplierInstallmentPaymentID,
|
||||||
|
SupplierInstallmentStatus,
|
||||||
|
SupplierInstallmentIsLunas,
|
||||||
|
SupplierInstallmentIsActive,
|
||||||
|
SupplierInstallmentCreated,
|
||||||
|
SupplierInstallmentCreatedUserID
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, 0, 'Pending', 'N', 'Y', NOW(), ?)";
|
||||||
|
|
||||||
|
$que = $this->db->query($sql, [
|
||||||
|
$row["PurchaseOrderID"],
|
||||||
|
$row["PurchaseOrderSupplierID"],
|
||||||
|
$row["SupplierInvoiceID"],
|
||||||
|
$amount,
|
||||||
|
$installDate,
|
||||||
|
$installDate,
|
||||||
|
$createdBy
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$que) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Gagal insert supplier_installment.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$installmentID = $this->db->insert_id();
|
||||||
|
$inserted++;
|
||||||
|
|
||||||
|
$created[] = [
|
||||||
|
"installmentID" => $installmentID,
|
||||||
|
"contractID" => $row["PurchaseOrderAssetContractID"],
|
||||||
|
"purchaseOrderID" => $row["PurchaseOrderID"],
|
||||||
|
"parentInvoiceID" => $row["SupplierInvoiceID"],
|
||||||
|
"parentInvoiceNumber" => $row["SupplierInvoiceNumber"],
|
||||||
|
"amount" => $amount,
|
||||||
|
"installDate" => $installDate,
|
||||||
|
"dueDate" => $dueDate
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->db->trans_status() === false) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Transaksi gagal.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
|
||||||
|
$this->sys_ok([
|
||||||
|
"startDate" => $startDate,
|
||||||
|
"endDate" => $endDate,
|
||||||
|
"totalEligible" => count($eligible),
|
||||||
|
"totalInserted" => $inserted,
|
||||||
|
"created" => $created
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
if ($this->db->trans_status() === false) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
}
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ambil data user berdasarkan userID untuk keperluan CRON.
|
||||||
|
* Jika user tidak ditemukan, kembalikan data default (tanpa branch/regional).
|
||||||
|
*
|
||||||
|
* @param int $userID
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getCronUser($userID)
|
||||||
|
{
|
||||||
|
$sql = "SELECT
|
||||||
|
M_UserID,
|
||||||
|
M_UserM_BranchID AS M_BranchID,
|
||||||
|
M_UserS_RegionalID AS S_RegionalID
|
||||||
|
FROM m_user
|
||||||
|
WHERE M_UserID = ?
|
||||||
|
LIMIT 1";
|
||||||
|
|
||||||
|
$qry = $this->db->query($sql, [$userID]);
|
||||||
|
if ($qry && $qry->num_rows() > 0) {
|
||||||
|
$user = $qry->row_array();
|
||||||
|
$user["loginLevel"] = "branch";
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User tidak ditemukan, gunakan data kosong agar proses tetap berjalan
|
||||||
|
return [
|
||||||
|
"M_UserID" => $userID,
|
||||||
|
"M_BranchID" => 0,
|
||||||
|
"S_RegionalID" => 0,
|
||||||
|
"loginLevel" => "branch"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hitung tanggal jatuh tempo berdasarkan tanggal acuan dan payment term (dalam hari).
|
||||||
|
*
|
||||||
|
* @param string $tanggal Format YYYY-MM-DD
|
||||||
|
* @param int $term Jumlah hari payment term
|
||||||
|
* @return string Tanggal jatuh tempo (YYYY-MM-DD)
|
||||||
|
*/
|
||||||
|
private function hitungJatuhTempo($tanggal, $term)
|
||||||
|
{
|
||||||
|
$hari = is_numeric($term) ? (int) $term : 0;
|
||||||
|
if ($hari < 0) {
|
||||||
|
$hari = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return date("Y-m-d", strtotime($tanggal . " +" . $hari . " days"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validasi apakah string adalah tanggal yang valid dengan format YYYY-MM-DD.
|
||||||
|
*
|
||||||
|
* @param string $tanggal
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isValidDate($tanggal)
|
||||||
|
{
|
||||||
|
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
||||||
|
return $d && $d->format("Y-m-d") === $tanggal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getEligibleInstallments — Steps 1–5 combined
|
||||||
|
*
|
||||||
|
* Returns contracts that:
|
||||||
|
* Step 1: Are active, not paid off, within date range, due date reached
|
||||||
|
* Step 2: Have approved & active PO
|
||||||
|
* Step 3: Have confirmed & active RO
|
||||||
|
* Step 4: Have a parent supplier_invoice with IsInstallment = 'Y'
|
||||||
|
* Step 5: Do NOT already have a supplier_installment for this month
|
||||||
|
*
|
||||||
|
* @param string $startDate YYYY-MM-DD
|
||||||
|
* @param string $endDate YYYY-MM-DD
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getEligibleInstallments($startDate, $endDate)
|
||||||
|
{
|
||||||
|
$dayOfMonth = (int) date("d", strtotime($endDate));
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
c.PurchaseOrderAssetContractID,
|
||||||
|
c.PurchaseOrderAssetContractInstallmentPayAmount,
|
||||||
|
c.PurchaseOrderAssetContractInstallmentDate,
|
||||||
|
c.PurchaseOrderAssetContractCreatedUserID,
|
||||||
|
po.PurchaseOrderID,
|
||||||
|
po.PurchaseOrderSupplierID,
|
||||||
|
si.SupplierInvoiceID,
|
||||||
|
si.SupplierInvoiceNumber
|
||||||
|
FROM purchase_order_asset_contract c
|
||||||
|
|
||||||
|
-- Step 2: PO must be Approved and Active
|
||||||
|
JOIN purchase_order po
|
||||||
|
ON po.PurchaseOrderID = c.PurchaseOrderAssetContractPurchaseOrderID
|
||||||
|
AND po.PurchaseOrderIsActive = 'Y'
|
||||||
|
AND po.PurchaseOrderStatus = 'Approved'
|
||||||
|
|
||||||
|
-- Step 3: RO must be Confirmed and Active
|
||||||
|
JOIN (
|
||||||
|
SELECT
|
||||||
|
rd.ReceiveOrderPoDetailPurchaseOrderID,
|
||||||
|
MIN(ro0.ReceiveOrderPoID) AS ReceiveOrderPoID,
|
||||||
|
MAX(ro0.ReceiveOrderPoConfirmed) AS ReceiveOrderPoConfirmed
|
||||||
|
FROM receive_order_po ro0
|
||||||
|
JOIN receive_order_po_detail rd
|
||||||
|
ON rd.ReceiveOrderPoDetailReceiveOrderPoID = ro0.ReceiveOrderPoID
|
||||||
|
AND rd.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
WHERE ro0.ReceiveOrderPoIsActive = 'Y'
|
||||||
|
AND ro0.ReceiveOrderPoConfirmed = 'Y'
|
||||||
|
GROUP BY rd.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
) ro ON ro.ReceiveOrderPoDetailPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
|
||||||
|
-- Step 4: Parent invoice must exist with IsInstallment = 'Y'
|
||||||
|
JOIN supplier_invoice si
|
||||||
|
ON si.SupplierInvoiceReceiveOrderPoID = ro.ReceiveOrderPoID
|
||||||
|
AND si.SupplierInvoiceIsActive = 'Y'
|
||||||
|
AND si.SupplierInvoiceIsInstallment = 'Y'
|
||||||
|
|
||||||
|
-- Step 1: Contract eligibility
|
||||||
|
WHERE c.PurchaseOrderAssetContractIsActive = 'Y'
|
||||||
|
AND c.PurchaseOrderAssetContractStatus = 'belum lunas'
|
||||||
|
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPayAmount, 0) > 0
|
||||||
|
AND IFNULL(c.PurchaseOrderAssetContractInstallmentPaid, 0)
|
||||||
|
< IFNULL(c.PurchaseOrderAssetContractInstallmentNumber, 0)
|
||||||
|
AND DATE(c.PurchaseOrderAssetContractStartDate) <= DATE(?)
|
||||||
|
AND (
|
||||||
|
c.PurchaseOrderAssetContractEndDate IS NULL
|
||||||
|
OR DATE(c.PurchaseOrderAssetContractEndDate) >= DATE(?)
|
||||||
|
)
|
||||||
|
AND IFNULL(c.PurchaseOrderAssetContractInstallmentDate, 1) <= ?
|
||||||
|
|
||||||
|
-- Step 5: Dedup — no existing supplier_installment this month (any status)
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM supplier_installment inst
|
||||||
|
WHERE inst.SupplierInstallmentIsActive = 'Y'
|
||||||
|
AND inst.SupplierInstallmentPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
AND DATE_FORMAT(inst.SupplierInstallmentDate, '%Y-%m') = DATE_FORMAT(?, '%Y-%m')
|
||||||
|
)
|
||||||
|
|
||||||
|
ORDER BY c.PurchaseOrderAssetContractID ASC";
|
||||||
|
|
||||||
|
$params = [$endDate, $startDate, $dayOfMonth, $endDate];
|
||||||
|
|
||||||
|
$qry = $this->db->query($sql, $params);
|
||||||
|
if (!$qry) {
|
||||||
|
$this->sys_error_db("Gagal mengambil daftar installment eligible.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qry->result_array();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PurchaseInvoiceInstallmentInsert
|
||||||
|
*
|
||||||
|
* Endpoint khusus untuk menyimpan supplier_invoice dan supplier_invoice_detail
|
||||||
|
* dari payload yang dikirim controller generator via cURL.
|
||||||
|
*/
|
||||||
|
class PurchaseInvoiceInstallmentInsert extends MY_Controller
|
||||||
|
{
|
||||||
|
var $db;
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Purchase Invoice Installment Insert";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function InsertSupplierInvoice()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$para = $this->sys_input;
|
||||||
|
|
||||||
|
$required = [
|
||||||
|
"nomorPI",
|
||||||
|
"tanggalPI",
|
||||||
|
"tanggalJatuhTempo",
|
||||||
|
"jumlahCicilan",
|
||||||
|
"catatan",
|
||||||
|
"deskripsi",
|
||||||
|
"userID",
|
||||||
|
"purchaseOrderAssetContractID",
|
||||||
|
"purchaseOrderID",
|
||||||
|
"receiveOrderPoID",
|
||||||
|
"supplierID",
|
||||||
|
"purchaseOrderSummaryID",
|
||||||
|
"purchaseOrderSummaryItemID",
|
||||||
|
"purchaseOrderSummaryItemUnitID"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($required as $field) {
|
||||||
|
if (!isset($para[$field]) || $para[$field] === "" || $para[$field] === null) {
|
||||||
|
throw new Exception("Field wajib belum lengkap: " . $field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tanggalPI = $para["tanggalPI"];
|
||||||
|
$tanggalJatuhTempo = $para["tanggalJatuhTempo"];
|
||||||
|
if (!$this->isValidDate($tanggalPI) || !$this->isValidDate($tanggalJatuhTempo)) {
|
||||||
|
throw new Exception("Format tanggal tidak valid. Gunakan YYYY-MM-DD.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$jumlahCicilan = (float) $para["jumlahCicilan"];
|
||||||
|
if ($jumlahCicilan <= 0) {
|
||||||
|
throw new Exception("jumlahCicilan harus lebih besar dari 0.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$receiveOrderPoID = (int) $para["receiveOrderPoID"];
|
||||||
|
$monthKey = date("Y-m", strtotime($tanggalPI));
|
||||||
|
|
||||||
|
$sqlDuplikat = "SELECT SupplierInvoiceID, SupplierInvoiceNumber
|
||||||
|
FROM supplier_invoice
|
||||||
|
WHERE SupplierInvoiceIsActive = 'Y'
|
||||||
|
AND SupplierInvoiceStatus = 'Draft'
|
||||||
|
AND SupplierInvoiceReceiveOrderPoID = ?
|
||||||
|
AND DATE_FORMAT(SupplierInvoiceDate, '%Y-%m') = ?
|
||||||
|
LIMIT 1";
|
||||||
|
|
||||||
|
$qryDuplikat = $this->db->query($sqlDuplikat, [$receiveOrderPoID, $monthKey]);
|
||||||
|
if (!$qryDuplikat) {
|
||||||
|
$this->sys_error_db("Gagal mengecek duplikasi supplier_invoice.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($qryDuplikat->num_rows() > 0) {
|
||||||
|
$existing = $qryDuplikat->row_array();
|
||||||
|
$this->sys_ok([
|
||||||
|
"duplicate" => true,
|
||||||
|
"supplierInvoiceID" => $existing["SupplierInvoiceID"],
|
||||||
|
"supplierInvoiceNumber" => $existing["SupplierInvoiceNumber"]
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_begin();
|
||||||
|
|
||||||
|
$sqlHeader = "INSERT INTO supplier_invoice (
|
||||||
|
SupplierInvoiceNumber,
|
||||||
|
SupplierInvoiceReceiveOrderPoID,
|
||||||
|
SupplierInvoiceDate,
|
||||||
|
SupplierInvoiceDueDate,
|
||||||
|
SupplierInvoiceDraftPaymentDate,
|
||||||
|
SupplierInvoiceSupplierID,
|
||||||
|
SupplierInvoiceSupplierInvoiceNumber,
|
||||||
|
SupplierInvoiceSupplierInvoiceDate,
|
||||||
|
SupplierInvoiceSubTotal,
|
||||||
|
SupplierInvoiceDiscountPercent,
|
||||||
|
SupplierInvoiceDiscountAmount,
|
||||||
|
SupplierInvoiceTaxPercentPph,
|
||||||
|
SupplierInvoiceTaxAmountPph,
|
||||||
|
SupplierInvoiceTaxPercentPpn,
|
||||||
|
SupplierInvoiceTaxAmountPpn,
|
||||||
|
SupplierInvoiceShippingCost,
|
||||||
|
SupplierInvoiceAdjustmentAmount,
|
||||||
|
SupplierInvoiceAdjustmentNote,
|
||||||
|
SupplierInvoiceGrandTotal,
|
||||||
|
SupplierInvoiceUnpaid,
|
||||||
|
SupplierInvoiceNote,
|
||||||
|
SupplierInvoiceStatus,
|
||||||
|
SupplierInvoiceCreatedUserID
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||||
|
|
||||||
|
$qryHeader = $this->db->query($sqlHeader, [
|
||||||
|
$para["nomorPI"],
|
||||||
|
$receiveOrderPoID,
|
||||||
|
$tanggalPI,
|
||||||
|
$tanggalJatuhTempo,
|
||||||
|
$tanggalPI,
|
||||||
|
(int) $para["supplierID"],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
$jumlahCicilan,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
$jumlahCicilan,
|
||||||
|
$jumlahCicilan,
|
||||||
|
$para["catatan"],
|
||||||
|
"Draft",
|
||||||
|
(int) $para["userID"]
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$qryHeader) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Gagal insert header supplier_invoice.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$supplierInvoiceID = $this->db->insert_id();
|
||||||
|
|
||||||
|
$sqlDetail = "INSERT INTO supplier_invoice_detail (
|
||||||
|
SupplierInvoiceDetailSupplierInvoiceID,
|
||||||
|
SupplierInvoiceDetailPurchaseOrderID,
|
||||||
|
SupplierInvoiceDetailReceiveOrderPoID,
|
||||||
|
SupplierInvoiceDetailPurchaseOrderSummaryID,
|
||||||
|
SupplierInvoiceDetailItemID,
|
||||||
|
SupplierInvoiceDetailItemUnitID,
|
||||||
|
SupplierInvoiceDetailDescription,
|
||||||
|
SupplierInvoiceDetailQty,
|
||||||
|
SupplierInvoiceDetailPrice,
|
||||||
|
SupplierInvoiceDetailDiscountPercent,
|
||||||
|
SupplierInvoiceDetailDiscountDiscountRupiah,
|
||||||
|
SupplierInvoiceDetailDiscountDiscountType,
|
||||||
|
SupplierInvoiceDetailDiscountPoProrata,
|
||||||
|
SupplierInvoiceDetailDiscountAmount,
|
||||||
|
SupplierInvoiceDetailTotal,
|
||||||
|
SupplierInvoiceDetailUnpaid,
|
||||||
|
SupplierInvoiceDetailCreatedUserID
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||||
|
|
||||||
|
$qryDetail = $this->db->query($sqlDetail, [
|
||||||
|
$supplierInvoiceID,
|
||||||
|
(int) $para["purchaseOrderID"],
|
||||||
|
$receiveOrderPoID,
|
||||||
|
(int) $para["purchaseOrderSummaryID"],
|
||||||
|
(int) $para["purchaseOrderSummaryItemID"],
|
||||||
|
(int) $para["purchaseOrderSummaryItemUnitID"],
|
||||||
|
$para["deskripsi"],
|
||||||
|
1,
|
||||||
|
$jumlahCicilan,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"R",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
$jumlahCicilan,
|
||||||
|
$jumlahCicilan,
|
||||||
|
(int) $para["userID"]
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$qryDetail) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Gagal insert detail supplier_invoice_detail.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->db->trans_status() === false) {
|
||||||
|
$this->db->trans_rollback();
|
||||||
|
$this->sys_error_db("Transaksi insert supplier_invoice gagal.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->trans_commit();
|
||||||
|
|
||||||
|
$this->sys_ok([
|
||||||
|
"duplicate" => false,
|
||||||
|
"supplierInvoiceID" => $supplierInvoiceID,
|
||||||
|
"supplierInvoiceNumber" => $para["nomorPI"]
|
||||||
|
]);
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isValidDate($tanggal)
|
||||||
|
{
|
||||||
|
$d = DateTime::createFromFormat("Y-m-d", $tanggal);
|
||||||
|
return $d && $d->format("Y-m-d") === $tanggal;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,29 +28,92 @@ class Billv2 extends MY_Controller {
|
|||||||
$offset = ($params['currentpage'] - 1) * $limit;
|
$offset = ($params['currentpage'] - 1) * $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_base = "SELECT
|
// ── UNION base — invoice + downpayment + installment ───
|
||||||
SupplierPaymentID,
|
$sql_base = "
|
||||||
SupplierPaymentDate,
|
SELECT
|
||||||
SupplierPaymentNumber,
|
sp.SupplierPaymentID,
|
||||||
SupplierPaymentAmount,
|
sp.SupplierPaymentDate,
|
||||||
SupplierPaymentStatus,
|
sp.SupplierPaymentNumber,
|
||||||
SupplierPaymentIsVerif,
|
sp.SupplierPaymentAmount,
|
||||||
SupplierPaymentIsApproved,
|
sp.SupplierPaymentStatus,
|
||||||
SupplierInvoiceID,
|
sp.SupplierPaymentIsVerif,
|
||||||
SupplierInvoiceNumber,
|
sp.SupplierPaymentIsApproved,
|
||||||
SupplierInvoiceDraftPaymentDate,
|
sp.SupplierPaymentIsActive,
|
||||||
SupplierCode,
|
si.SupplierInvoiceID,
|
||||||
SupplierName
|
si.SupplierInvoiceNumber,
|
||||||
FROM supplier_payment
|
si.SupplierInvoiceDraftPaymentDate,
|
||||||
JOIN supplier_invoice ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID
|
sup.SupplierCode,
|
||||||
AND SupplierPaymentNumber LIKE ?
|
sup.SupplierName,
|
||||||
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
'INVOICE' AS type
|
||||||
AND (SupplierPaymentStatus = ? OR ? = 'All')
|
FROM supplier_payment sp
|
||||||
JOIN supplier ON SupplierID = SupplierInvoiceSupplierID
|
JOIN supplier_invoice si
|
||||||
WHERE SupplierPaymentIsActive = 'Y'
|
ON si.SupplierInvoiceID = sp.SupplierPaymentSupplierInvoiceID
|
||||||
ORDER BY SupplierPaymentID DESC";
|
JOIN supplier sup
|
||||||
|
ON sup.SupplierID = si.SupplierInvoiceSupplierID
|
||||||
|
WHERE sp.SupplierPaymentSupplierInvoiceID > 0
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
sp.SupplierPaymentID,
|
||||||
|
sp.SupplierPaymentDate,
|
||||||
|
sp.SupplierPaymentNumber,
|
||||||
|
sp.SupplierPaymentAmount,
|
||||||
|
sp.SupplierPaymentStatus,
|
||||||
|
sp.SupplierPaymentIsVerif,
|
||||||
|
sp.SupplierPaymentIsApproved,
|
||||||
|
sp.SupplierPaymentIsActive,
|
||||||
|
dp.SupplierDownpaymentID * -1 AS SupplierInvoiceID,
|
||||||
|
CONCAT('DP-', po.PurchaseOrderNumber) AS SupplierInvoiceNumber,
|
||||||
|
dp.SupplierDownpaymentDueDate AS SupplierInvoiceDraftPaymentDate,
|
||||||
|
dp_sup.SupplierCode AS SupplierCode,
|
||||||
|
dp_sup.SupplierName AS SupplierName,
|
||||||
|
'DP' AS type
|
||||||
|
FROM supplier_payment sp
|
||||||
|
JOIN supplier_downpayment dp
|
||||||
|
ON dp.SupplierDownpaymentID = sp.SupplierPaymentSupplierDownpaymentID
|
||||||
|
JOIN supplier dp_sup
|
||||||
|
ON dp_sup.SupplierID = dp.SupplierDownpaymentSupplierID
|
||||||
|
JOIN purchase_order po
|
||||||
|
ON po.PurchaseOrderID = dp.SupplierDownpaymentPurchasOrderID
|
||||||
|
WHERE sp.SupplierPaymentSupplierDownpaymentID IS NOT NULL
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
sp.SupplierPaymentID,
|
||||||
|
sp.SupplierPaymentDate,
|
||||||
|
sp.SupplierPaymentNumber,
|
||||||
|
sp.SupplierPaymentAmount,
|
||||||
|
sp.SupplierPaymentStatus,
|
||||||
|
sp.SupplierPaymentIsVerif,
|
||||||
|
sp.SupplierPaymentIsApproved,
|
||||||
|
sp.SupplierPaymentIsActive,
|
||||||
|
0 AS SupplierInvoiceID,
|
||||||
|
CONCAT('INST-', si_inst.SupplierInvoiceNumber) AS SupplierInvoiceNumber,
|
||||||
|
inst.SupplierInstallmentDueDate AS SupplierInvoiceDraftPaymentDate,
|
||||||
|
inst_sup.SupplierCode AS SupplierCode,
|
||||||
|
inst_sup.SupplierName AS SupplierName,
|
||||||
|
'INSTALLMENT' AS type
|
||||||
|
FROM supplier_payment sp
|
||||||
|
JOIN supplier_installment inst
|
||||||
|
ON inst.SupplierInstallmentID = sp.SupplierPaymentSupplierInstallmentID
|
||||||
|
JOIN supplier_invoice si_inst
|
||||||
|
ON si_inst.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
||||||
|
JOIN supplier inst_sup
|
||||||
|
ON inst_sup.SupplierID = inst.SupplierInstallmentSupplierID
|
||||||
|
WHERE sp.SupplierPaymentSupplierInstallmentID IS NOT NULL";
|
||||||
|
|
||||||
|
// ── Outer: common filters + ordering + pagination ───────
|
||||||
|
$sql_data = "
|
||||||
|
SELECT * FROM ($sql_base) AS combined
|
||||||
|
WHERE SupplierPaymentIsActive = 'Y'
|
||||||
|
AND SupplierPaymentNumber LIKE ?
|
||||||
|
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
||||||
|
AND (SupplierPaymentStatus = ? OR ? = 'All')
|
||||||
|
ORDER BY SupplierPaymentID DESC
|
||||||
|
LIMIT ? OFFSET ?";
|
||||||
|
|
||||||
$sql_data = $sql_base . " LIMIT ? OFFSET ? ";
|
|
||||||
$que_data = $this->db->query($sql_data, [
|
$que_data = $this->db->query($sql_data, [
|
||||||
$keyword, $params['startdate'], $params['enddate'],
|
$keyword, $params['startdate'], $params['enddate'],
|
||||||
$params['status'], $params['status'], $limit, $offset
|
$params['status'], $params['status'], $limit, $offset
|
||||||
@@ -59,7 +122,13 @@ class Billv2 extends MY_Controller {
|
|||||||
throw new Exception("[Error] failed get data supplier payment", 2);
|
throw new Exception("[Error] failed get data supplier payment", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS x";
|
// ── COUNT — wrap UNION in outer filter ──────────────────
|
||||||
|
$sql_total = "SELECT COUNT(*) AS total FROM ($sql_base) AS combined
|
||||||
|
WHERE SupplierPaymentIsActive = 'Y'
|
||||||
|
AND SupplierPaymentNumber LIKE ?
|
||||||
|
AND (SupplierPaymentDate BETWEEN DATE(?) AND DATE(?))
|
||||||
|
AND (SupplierPaymentStatus = ? OR ? = 'All')";
|
||||||
|
|
||||||
$que_total = $this->db->query($sql_total, [
|
$que_total = $this->db->query($sql_total, [
|
||||||
$keyword, $params['startdate'], $params['enddate'],
|
$keyword, $params['startdate'], $params['enddate'],
|
||||||
$params['status'], $params['status']
|
$params['status'], $params['status']
|
||||||
@@ -70,11 +139,10 @@ class Billv2 extends MY_Controller {
|
|||||||
|
|
||||||
$output = [
|
$output = [
|
||||||
"records" => $que_data->result_array(),
|
"records" => $que_data->result_array(),
|
||||||
"total" =>$que_total->row_array()['total']
|
"total" => $que_total->row_array()['total']
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->sys_ok($output);
|
$this->sys_ok($output);
|
||||||
exit;
|
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
$message = $exc->getMessage();
|
$message = $exc->getMessage();
|
||||||
$code = $exc->getCode();
|
$code = $exc->getCode();
|
||||||
@@ -96,70 +164,169 @@ class Billv2 extends MY_Controller {
|
|||||||
|
|
||||||
$para = $this->sys_input;
|
$para = $this->sys_input;
|
||||||
|
|
||||||
$sql = "SELECT
|
// ── Detect payment type ──────────────────────────────────
|
||||||
SupplierInvoiceID,
|
$sql_type = "SELECT
|
||||||
SupplierInvoiceRefNumber,
|
SupplierPaymentSupplierInvoiceID,
|
||||||
SupplierInvoiceDeliveryOrderNumber,
|
SupplierPaymentSupplierDownpaymentID,
|
||||||
SupplierInvoiceSupplierInvoiceNumber,
|
SupplierPaymentSupplierInstallmentID
|
||||||
SupplierInvoiceSupplierInvoiceDate,
|
FROM supplier_payment
|
||||||
SupplierInvoiceSubTotal,
|
WHERE SupplierPaymentID = ? AND SupplierPaymentIsActive = 'Y'";
|
||||||
SupplierInvoiceTaxPercentPph,
|
|
||||||
SupplierInvoiceTaxPercentPpn,
|
|
||||||
SupplierInvoiceTaxAmountPpn,
|
|
||||||
SupplierInvoiceDiscountAmount,
|
|
||||||
SupplierInvoiceDiscountPercent,
|
|
||||||
SupplierInvoiceShippingCost,
|
|
||||||
SupplierInvoiceGrandTotal,
|
|
||||||
SupplierInvoiceAdjustmentAmount,
|
|
||||||
SupplierInvoiceAdjustmentNote,
|
|
||||||
SupplierInvoiceNote,
|
|
||||||
IF (SupplierInvoiceDiscountAmount > 0, 'R', 'P') AS DiscountType
|
|
||||||
FROM supplier_payment
|
|
||||||
JOIN supplier_invoice ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
|
||||||
AND SupplierPaymentID = ?
|
|
||||||
AND SupplierPaymentIsActive = 'Y'";
|
|
||||||
$que = $this->db->query($sql, [$para['paymentID']]);
|
|
||||||
if (!$que) {
|
|
||||||
throw new Exception("[Error] failed get row data", 2);
|
|
||||||
}
|
|
||||||
$data = $que->row_array();
|
|
||||||
|
|
||||||
$sql_detail = "SELECT
|
$que_type = $this->db->query($sql_type, [$para['paymentID']]);
|
||||||
SupplierInvoiceDetailID,
|
if (!$que_type) {
|
||||||
SupplierInvoiceDetailSupplierInvoiceID,
|
throw new Exception("[Error] failed get payment header", 2);
|
||||||
SupplierInvoiceDetailPurchaseOrderID,
|
}
|
||||||
SupplierInvoiceDetailPurchaseOrderSummaryID,
|
$payment = $que_type->row_array();
|
||||||
SupplierInvoiceDetailReceiveOrderPoID,
|
if (!$payment) {
|
||||||
SupplierInvoiceDetailReceiveOrderPoDetailID,
|
throw new Exception("[Error] payment not found", 2);
|
||||||
SupplierInvoiceDetailItemID,
|
|
||||||
SupplierInvoiceDetailItemUnitID,
|
|
||||||
SupplierInvoiceDetailDescription,
|
|
||||||
SupplierInvoiceDetailQty,
|
|
||||||
SupplierInvoiceDetailPrice,
|
|
||||||
SupplierInvoiceDetailDiscountPercent,
|
|
||||||
SupplierInvoiceDetailDiscountDiscountRupiah,
|
|
||||||
SupplierInvoiceDetailDiscountDiscountType,
|
|
||||||
SupplierInvoiceDetailDiscountAmount,
|
|
||||||
(SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice,
|
|
||||||
SupplierInvoiceDetailDiscountPoProrata,
|
|
||||||
SupplierInvoiceDetailTotal,
|
|
||||||
M_ItemCode,
|
|
||||||
M_ItemDesc
|
|
||||||
FROM supplier_payment_detail
|
|
||||||
JOIN supplier_invoice_detail ON SupplierInvoiceDetailIsActive = 'Y'
|
|
||||||
AND SupplierPaymentDetailSupplierPaymentID = ?
|
|
||||||
AND SupplierInvoiceDetailSupplierInvoiceID = ?
|
|
||||||
JOIN m_item ON M_ItemID = SupplierInvoiceDetailItemID
|
|
||||||
AND M_ItemIsActive = 'Y'
|
|
||||||
GROUP BY SupplierInvoiceDetailID";
|
|
||||||
$que_detail = $this->db->query($sql_detail, [
|
|
||||||
$para['paymentID'], $data['SupplierInvoiceID']
|
|
||||||
]);
|
|
||||||
if (!$que_detail) {
|
|
||||||
throw new Exception("[Error] failed to get item payments", 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['detail'] = $que_detail->result_array();
|
// ── INVOICE branch ──────────────────────────────────────
|
||||||
|
if ($payment['SupplierPaymentSupplierInvoiceID'] > 0) {
|
||||||
|
$sql = "SELECT
|
||||||
|
si.SupplierInvoiceSubTotal,
|
||||||
|
si.SupplierInvoiceShippingCost,
|
||||||
|
si.SupplierInvoiceDiscountPercent,
|
||||||
|
si.SupplierInvoiceDiscountAmount,
|
||||||
|
si.SupplierInvoiceTaxPercentPpn,
|
||||||
|
si.SupplierInvoiceTaxAmountPpn,
|
||||||
|
si.SupplierInvoiceGrandTotal,
|
||||||
|
si.SupplierInvoiceID,
|
||||||
|
'INVOICE' AS type
|
||||||
|
FROM supplier_payment sp
|
||||||
|
JOIN supplier_invoice si
|
||||||
|
ON si.SupplierInvoiceID = sp.SupplierPaymentSupplierInvoiceID
|
||||||
|
WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'";
|
||||||
|
|
||||||
|
$que = $this->db->query($sql, [$para['paymentID']]);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception("[Error] failed get row data", 2);
|
||||||
|
}
|
||||||
|
$data = $que->row_array();
|
||||||
|
|
||||||
|
$sql_detail = "SELECT
|
||||||
|
M_ItemDesc,
|
||||||
|
SupplierInvoiceDetailQty,
|
||||||
|
SupplierInvoiceDetailPrice,
|
||||||
|
SupplierInvoiceDetailDiscountAmount,
|
||||||
|
(SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice,
|
||||||
|
SupplierInvoiceDetailTotal
|
||||||
|
FROM supplier_payment_detail
|
||||||
|
JOIN supplier_invoice_detail
|
||||||
|
ON SupplierInvoiceDetailIsActive = 'Y'
|
||||||
|
AND SupplierPaymentDetailSupplierPaymentID = ?
|
||||||
|
AND SupplierInvoiceDetailSupplierInvoiceID = ?
|
||||||
|
JOIN m_item
|
||||||
|
ON M_ItemID = SupplierInvoiceDetailItemID AND M_ItemIsActive = 'Y'
|
||||||
|
GROUP BY SupplierInvoiceDetailID";
|
||||||
|
|
||||||
|
$que_detail = $this->db->query($sql_detail, [
|
||||||
|
$para['paymentID'], $data['SupplierInvoiceID']
|
||||||
|
]);
|
||||||
|
if (!$que_detail) {
|
||||||
|
throw new Exception("[Error] failed to get item payments", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['SupplierInvoiceID']);
|
||||||
|
$data['detail'] = $que_detail->result_array();
|
||||||
|
|
||||||
|
// ── DOWNPAYMENT branch ──────────────────────────────────
|
||||||
|
} elseif ($payment['SupplierPaymentSupplierDownpaymentID'] > 0) {
|
||||||
|
$sql = "SELECT
|
||||||
|
dp.SupplierDownpaymentPurchasOrderID,
|
||||||
|
dp.SupplierDownpaymentAmount AS SupplierInvoiceSubTotal,
|
||||||
|
0 AS SupplierInvoiceShippingCost,
|
||||||
|
0 AS SupplierInvoiceDiscountPercent,
|
||||||
|
0 AS SupplierInvoiceDiscountAmount,
|
||||||
|
0 AS SupplierInvoiceTaxPercentPpn,
|
||||||
|
0 AS SupplierInvoiceTaxAmountPpn,
|
||||||
|
dp.SupplierDownpaymentAmount AS SupplierInvoiceGrandTotal,
|
||||||
|
'DP' AS type
|
||||||
|
FROM supplier_payment sp
|
||||||
|
JOIN supplier_downpayment dp
|
||||||
|
ON dp.SupplierDownpaymentID = sp.SupplierPaymentSupplierDownpaymentID
|
||||||
|
WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'";
|
||||||
|
|
||||||
|
$que = $this->db->query($sql, [$para['paymentID']]);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception("[Error] failed get DP row data", 2);
|
||||||
|
}
|
||||||
|
$data = $que->row_array();
|
||||||
|
|
||||||
|
$sql_detail = "SELECT
|
||||||
|
CONCAT('DP-', M_ItemDesc) AS M_ItemDesc,
|
||||||
|
PurchaseOrderDetailQty AS SupplierInvoiceDetailQty,
|
||||||
|
PurchaseOrderDetailPrice AS SupplierInvoiceDetailPrice,
|
||||||
|
PurchaseOrderSummaryDiscountAmount AS SupplierInvoiceDetailDiscountAmount,
|
||||||
|
(PurchaseOrderDetailPrice - PurchaseOrderSummaryDiscountAmount) AS DiscountedPrice,
|
||||||
|
PurchaseOrderSummaryTotal AS SupplierInvoiceDetailTotal
|
||||||
|
FROM supplier_downpayment
|
||||||
|
JOIN purchase_order
|
||||||
|
ON SupplierDownpaymentPurchasOrderID = PurchaseOrderID
|
||||||
|
JOIN purchase_order_detail
|
||||||
|
ON PurchaseOrderDetailPurchaseOrderID = PurchaseOrderID
|
||||||
|
AND PurchaseOrderDetailIsActive = 'Y'
|
||||||
|
JOIN purchase_order_summary
|
||||||
|
ON PurchaseOrderSummaryID = PurchaseOrderDetailPurchaseSummaryID
|
||||||
|
AND PurchaseOrderSummaryIsActive = 'Y'
|
||||||
|
JOIN m_item
|
||||||
|
ON M_ItemID = PurchaseOrderDetailItemID
|
||||||
|
WHERE SupplierDownpaymentPurchasOrderID = ?";
|
||||||
|
|
||||||
|
$que_detail = $this->db->query($sql_detail, [
|
||||||
|
$data['SupplierDownpaymentPurchasOrderID']
|
||||||
|
]);
|
||||||
|
if (!$que_detail) {
|
||||||
|
throw new Exception('failed to get dp detail', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['detail'] = $que_detail->result_array();
|
||||||
|
} else {
|
||||||
|
$sql = "SELECT
|
||||||
|
inst.SupplierInstallmentAmount AS SupplierInvoiceSubTotal,
|
||||||
|
0 AS SupplierInvoiceShippingCost,
|
||||||
|
0 AS SupplierInvoiceDiscountPercent,
|
||||||
|
0 AS SupplierInvoiceDiscountAmount,
|
||||||
|
0 AS SupplierInvoiceTaxPercentPpn,
|
||||||
|
0 AS SupplierInvoiceTaxAmountPpn,
|
||||||
|
inst.SupplierInstallmentAmount AS SupplierInvoiceGrandTotal,
|
||||||
|
si.SupplierInvoiceID,
|
||||||
|
'INSTALLMENT' AS type
|
||||||
|
FROM supplier_payment sp
|
||||||
|
JOIN supplier_installment inst
|
||||||
|
ON inst.SupplierInstallmentID = sp.SupplierPaymentSupplierInstallmentID
|
||||||
|
JOIN supplier_invoice si
|
||||||
|
ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
||||||
|
WHERE sp.SupplierPaymentID = ? AND sp.SupplierPaymentIsActive = 'Y'";
|
||||||
|
|
||||||
|
$que = $this->db->query($sql, [$para['paymentID']]);
|
||||||
|
if (!$que) {
|
||||||
|
throw new Exception("[Error] failed get Installment row data", 2);
|
||||||
|
}
|
||||||
|
$data = $que->row_array();
|
||||||
|
|
||||||
|
$sql_detail = "SELECT
|
||||||
|
M_ItemDesc,
|
||||||
|
SupplierInvoiceDetailQty,
|
||||||
|
SupplierInvoiceDetailPrice,
|
||||||
|
SupplierInvoiceDetailDiscountAmount,
|
||||||
|
(SupplierInvoiceDetailPrice - SupplierInvoiceDetailDiscountAmount) AS DiscountedPrice,
|
||||||
|
SupplierInvoiceDetailTotal
|
||||||
|
FROM supplier_invoice_detail
|
||||||
|
JOIN m_item
|
||||||
|
ON M_ItemID = SupplierInvoiceDetailItemID AND M_ItemIsActive = 'Y'
|
||||||
|
WHERE SupplierInvoiceDetailSupplierInvoiceID = ?
|
||||||
|
AND SupplierInvoiceDetailIsActive = 'Y'
|
||||||
|
GROUP BY SupplierInvoiceDetailID";
|
||||||
|
|
||||||
|
$que_detail = $this->db->query($sql_detail, [$data['SupplierInvoiceID']]);
|
||||||
|
if (!$que_detail) {
|
||||||
|
throw new Exception("[Error] failed to get installment item payments", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['SupplierInvoiceID']);
|
||||||
|
$data['detail'] = $que_detail->result_array();
|
||||||
|
}
|
||||||
|
|
||||||
$this->sys_ok($data);
|
$this->sys_ok($data);
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
class Bill extends MY_Controller
|
class Bill extends MY_Controller
|
||||||
{
|
{
|
||||||
var $db_onedev;
|
var $db_onedev;
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
echo "Bill API";
|
echo "Bill API";
|
||||||
}
|
}
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->db_onedev = $this->load->database("onedev", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add_notes($orderid){
|
public function __construct()
|
||||||
$sql = " SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->db_onedev = $this->load->database("onedev", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add_notes($orderid)
|
||||||
|
{
|
||||||
|
$sql = "SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
||||||
SupplierPaymentID as note_id,
|
SupplierPaymentID as note_id,
|
||||||
SupplierPaymentDetailSupplierInvoiceDetailID as detail_id,
|
SupplierPaymentDetailSupplierInvoiceDetailID as detail_id,
|
||||||
SupplierPaymentDate as note_date,
|
SupplierPaymentDate as note_date,
|
||||||
@@ -45,58 +47,200 @@ class Bill extends MY_Controller
|
|||||||
AND
|
AND
|
||||||
SupplierPaymentIsActive = 'Y'
|
SupplierPaymentIsActive = 'Y'
|
||||||
GROUP BY SupplierPaymentID";
|
GROUP BY SupplierPaymentID";
|
||||||
$query = $this->db_onedev->query($sql);
|
$query = $this->db_onedev->query($sql);
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
if($rows){
|
if ($rows) {
|
||||||
foreach($rows as $k => $v){
|
foreach ($rows as $k => $v) {
|
||||||
$rows[$k]['tests'] = $this->add_tests($v['note_id']);
|
$rows[$k]['tests'] = $this->add_tests($v['note_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $rows;
|
return $rows;
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db("get notes", $this->db_onedev);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
public function add_notes_downpayment($orderid)
|
||||||
$this->sys_error_db("get notes", $this->db_onedev);
|
{
|
||||||
exit;
|
$sql = "SELECT SupplierPaymentSupplierDownpaymentID AS note_order_id,
|
||||||
}
|
SupplierPaymentID AS note_id,
|
||||||
}
|
SupplierDownpaymentID AS detail_id,
|
||||||
public function add_tagihans($orderid){
|
SupplierPaymentDate AS note_date,
|
||||||
$sql = "SELECT SupplierInvoiceID as tagihan_id,
|
SupplierPaymentNumber AS note_number,
|
||||||
PurchaseOrderNumber as tagihan_number,
|
GROUP_CONCAT(DISTINCT coaDescription separator ' , ') AS paymenttypes_name,
|
||||||
jurnalTxDescription as pasien,
|
SUM(SupplierDownpaymentAmount) AS note_amount,
|
||||||
jurnalTxCredit as tagihan_total,
|
n.M_UserUsername AS note_user,
|
||||||
IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan,
|
SupplierDownpaymentIsActive AS note_active,
|
||||||
0 as tagihan_bayar,
|
'N' AS show_detail,
|
||||||
DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate,
|
SupplierPaymentNote AS keterangan,
|
||||||
SupplierInvoiceIsActive as tagihan_active,
|
SupplierPaymentCoaID,
|
||||||
'N' as show_detail,
|
coaID,
|
||||||
jurnalTxID SupplierInvoiceDetailID,
|
coaDescription,
|
||||||
PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID
|
SupplierPaymentIsConfirm,
|
||||||
|
CONCAT(
|
||||||
|
'Confirmed by : ',c.M_UserUsername, ' ',
|
||||||
|
DATE_FORMAT(SupplierPaymentConfirmDate, '%d-%m-%Y %H:%i')
|
||||||
|
) AS d_confirm,
|
||||||
|
SupplierPaymentIsApproved,
|
||||||
|
CONCAT(
|
||||||
|
'Approved by : ',a.M_UserUsername, ' ',
|
||||||
|
DATE_FORMAT(SupplierPaymentApprovedDate,'%d-%m-%Y %H:%i')
|
||||||
|
) AS d_approved,
|
||||||
|
CONCAT(
|
||||||
|
'Verified by : ',b.M_UserUsername, ' ',
|
||||||
|
DATE_FORMAT(SupplierPaymentVerifDate,'%d-%m-%Y %H:%i')
|
||||||
|
) AS d_verif
|
||||||
|
FROM supplier_payment
|
||||||
|
JOIN supplier_downpayment
|
||||||
|
ON SupplierDownpaymentID = SupplierPaymentSupplierDownpaymentID
|
||||||
|
AND SupplierDownpaymentIsActive = 'Y'
|
||||||
|
LEFT JOIN coa ON SupplierPaymentCoaID = coaID
|
||||||
|
LEFT JOIN m_user n ON SupplierPaymentUserID = n.M_UserID
|
||||||
|
LEFT JOIN m_user c ON SupplierPaymentConfirmUserID = c.M_UserID
|
||||||
|
LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID
|
||||||
|
LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID
|
||||||
|
WHERE SupplierPaymentSupplierDownpaymentID = {$orderid}
|
||||||
|
AND SupplierPaymentIsActive = 'Y'
|
||||||
|
GROUP BY SupplierPaymentID";
|
||||||
|
$query = $this->db_onedev->query($sql);
|
||||||
|
if ($query) {
|
||||||
|
$rows = $query->result_array();
|
||||||
|
return $rows ?: [];
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db("get DP notes", $this->db_onedev);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FROM supplier_invoice
|
public function add_notes_installment($orderid)
|
||||||
JOIN receive_order_po ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
{
|
||||||
JOIN receive_order_po_detail ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID
|
$sql = "SELECT SupplierPaymentSupplierInstallmentID as note_order_id,
|
||||||
JOIN purchase_order ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
SupplierPaymentID as note_id,
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
SupplierInstallmentID as detail_id,
|
||||||
JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563
|
SupplierPaymentDate as note_date,
|
||||||
LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierInvoiceIsActive = 'Y'
|
SupplierPaymentNumber as note_number,
|
||||||
LEFT JOIN supplier_payment_detail ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID AND SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID AND SupplierPaymentDetailIsActive = 'Y'
|
GROUP_CONCAT(DISTINCT coaDescription separator ' , ') as paymenttypes_name,
|
||||||
WHERE
|
SUM(SupplierInstallmentAmount) as note_amount,
|
||||||
SupplierInvoiceID = {$orderid}
|
n.M_UserUsername as note_user,
|
||||||
GROUP BY jurnalTxID
|
SupplierInstallmentIsActive as note_active,
|
||||||
";
|
'N' as show_detail,
|
||||||
$query = $this->db_onedev->query($sql);
|
SupplierPaymentNote as keterangan,
|
||||||
if ($query) {
|
SupplierPaymentCoaID,
|
||||||
$rows = $query->result_array();
|
coaID,
|
||||||
return $rows;
|
coaDescription,
|
||||||
|
SupplierPaymentIsConfirm,
|
||||||
|
CONCAT(
|
||||||
|
'Confirmed by : ',c.M_UserUsername, ' ',
|
||||||
|
DATE_FORMAT(SupplierPaymentConfirmDate,'%d-%m-%Y %H:%i')
|
||||||
|
) AS d_confirm,
|
||||||
|
SupplierPaymentIsApproved,
|
||||||
|
CONCAT(
|
||||||
|
'Approved by : ',a.M_UserUsername, ' ',
|
||||||
|
DATE_FORMAT(SupplierPaymentApprovedDate,'%d-%m-%Y %H:%i')
|
||||||
|
) AS d_approved,
|
||||||
|
CONCAT(
|
||||||
|
'Verified by : ',b.M_UserUsername, ' ',
|
||||||
|
DATE_FORMAT(SupplierPaymentVerifDate,'%d-%m-%Y %H:%i')
|
||||||
|
) AS d_verif
|
||||||
|
FROM supplier_payment
|
||||||
|
JOIN supplier_installment
|
||||||
|
ON SupplierInstallmentID = SupplierPaymentSupplierInstallmentID
|
||||||
|
AND SupplierInstallmentIsActive = 'Y'
|
||||||
|
LEFT JOIN coa ON SupplierPaymentCoaID = coaID
|
||||||
|
LEFT JOIN m_user n ON SupplierPaymentUserID = n.M_UserID
|
||||||
|
LEFT JOIN m_user c ON SupplierPaymentConfirmUserID = c.M_UserID
|
||||||
|
LEFT JOIN m_user a ON SupplierPaymentApprovedUserID = a.M_UserID
|
||||||
|
LEFT JOIN m_user b ON SupplierPaymentVerifUserID = b.M_UserID
|
||||||
|
WHERE SupplierPaymentSupplierInstallmentID = {$orderid}
|
||||||
|
AND SupplierPaymentIsActive = 'Y'
|
||||||
|
GROUP BY SupplierPaymentID";
|
||||||
|
$query = $this->db_onedev->query($sql);
|
||||||
|
if ($query) {
|
||||||
|
$rows = $query->result_array();
|
||||||
|
return $rows ?: [];
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db("get Installment notes", $this->db_onedev);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
public function add_tagihans($orderid)
|
||||||
$this->sys_error_db("get notes", $this->db_onedev);
|
{
|
||||||
exit;
|
$sql_dp = "SELECT
|
||||||
}
|
Fa_ClassDownPaymentCoaID
|
||||||
}
|
FROM supplier_invoice_detail
|
||||||
public function add_tests($orderid){
|
JOIN m_item
|
||||||
$sql = " SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
ON M_ItemID = SupplierInvoiceDetailItemID
|
||||||
|
AND SupplierInvoiceDetailSupplierInvoiceID = ?
|
||||||
|
AND SupplierInvoiceDetailIsActive = 'Y'
|
||||||
|
AND SupplierInvoiceDetailIsVerified = 'Y'
|
||||||
|
JOIN fa_class
|
||||||
|
ON Fa_ClassID = M_ItemFa_ClassID
|
||||||
|
AND Fa_ClassIsActive = 'Y'";
|
||||||
|
$que_dp = $this->db_onedev->query($sql_dp, [$orderid]);
|
||||||
|
if (!$que_dp) {
|
||||||
|
$this->sys_error_db("failed to get coa id dp tagihans", $this->db_onedev);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$dataDP = $que_dp->result_array();
|
||||||
|
$excludeIds = array_column($dataDP, 'Fa_ClassDownPaymentCoaID');
|
||||||
|
$excludeIds[] = 563; // always excluded
|
||||||
|
$excludeIds = array_unique($excludeIds);
|
||||||
|
$excludeIds = array_values($excludeIds); // re-index
|
||||||
|
|
||||||
|
$notInPlaceholders = implode(',', array_fill(0, count($excludeIds), '?'));
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
SupplierInvoiceID as tagihan_id,
|
||||||
|
PurchaseOrderNumber as tagihan_number,
|
||||||
|
jurnalTxDescription as pasien,
|
||||||
|
jurnalTxCredit as tagihan_total,
|
||||||
|
IF(SupplierPaymentDetailID IS NULL , jurnalTxCredit, jurnalTxCredit - SUM(SupplierPaymentDetailAmount)) as tagihan_tagihan,
|
||||||
|
0 as tagihan_bayar,
|
||||||
|
DATE_FORMAT(SupplierInvoiceDueDate,'%d-%m-%Y') as tagihan_duedate,
|
||||||
|
SupplierInvoiceIsActive as tagihan_active,
|
||||||
|
'N' as show_detail,
|
||||||
|
jurnalTxID SupplierInvoiceDetailID,
|
||||||
|
PurchaseOrderID SupplierInvoiceDetailPurchaseOrderID
|
||||||
|
FROM supplier_invoice
|
||||||
|
JOIN receive_order_po
|
||||||
|
ON ReceiveOrderPoID = SupplierInvoiceReceiveOrderPoID
|
||||||
|
JOIN receive_order_po_detail
|
||||||
|
ON ReceiveOrderPoDetailReceiveOrderPoID = ReceiveOrderPoID
|
||||||
|
JOIN purchase_order
|
||||||
|
ON ReceiveOrderPoDetailPurchaseOrderID = PurchaseOrderID
|
||||||
|
JOIN jurnal_addon
|
||||||
|
ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
|
AND jurnalAddOnIsActive = 'Y'
|
||||||
|
JOIN jurnal_tx
|
||||||
|
ON jurnalTxJurnalID = jurnalAddOnJurnalID
|
||||||
|
AND jurnalTxIsActive = 'Y'
|
||||||
|
AND jurnalTxCredit <> 0
|
||||||
|
AND jurnalTxCoaID NOT IN ($notInPlaceholders)
|
||||||
|
LEFT JOIN supplier_payment
|
||||||
|
ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
||||||
|
AND SupplierInvoiceIsActive = 'Y'
|
||||||
|
LEFT JOIN supplier_payment_detail
|
||||||
|
ON SupplierPaymentDetailSupplierPaymentID = SupplierPaymentID
|
||||||
|
AND SupplierPaymentDetailSupplierInvoiceDetailID = jurnalTxID
|
||||||
|
AND SupplierPaymentDetailIsActive = 'Y'
|
||||||
|
WHERE SupplierInvoiceID = ?
|
||||||
|
GROUP BY jurnalTxID";
|
||||||
|
$query = $this->db_onedev->query($sql, array_merge($excludeIds, [$orderid]));
|
||||||
|
if ($query) {
|
||||||
|
$rows = $query->result_array();
|
||||||
|
return $rows;
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db("get tagihans", $this->db_onedev);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add_tests($orderid)
|
||||||
|
{
|
||||||
|
$sql = " SELECT SupplierPaymentSupplierInvoiceID as note_order_id,
|
||||||
SupplierPaymentID as note_id,
|
SupplierPaymentID as note_id,
|
||||||
SupplierPaymentDate as note_date,
|
SupplierPaymentDate as note_date,
|
||||||
SupplierPaymentNumber as note_number,
|
SupplierPaymentNumber as note_number,
|
||||||
@@ -116,142 +260,529 @@ class Bill extends MY_Controller
|
|||||||
WHERE
|
WHERE
|
||||||
SupplierPaymentID = {$orderid}
|
SupplierPaymentID = {$orderid}
|
||||||
GROUP BY SupplierPaymentDetailID";
|
GROUP BY SupplierPaymentDetailID";
|
||||||
$query = $this->db_onedev->query($sql);
|
$query = $this->db_onedev->query($sql);
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
if($rows){
|
if ($rows) {
|
||||||
}
|
}
|
||||||
return $rows;
|
return $rows;
|
||||||
|
} else {
|
||||||
} else {
|
$this->sys_error_db("get notes", $this->db_onedev);
|
||||||
$this->sys_error_db("get notes", $this->db_onedev);
|
exit;
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public function search()
|
|
||||||
{
|
|
||||||
//# cek token valid
|
|
||||||
if (! $this->isLogin) {
|
|
||||||
$this->sys_error("Invalid Token");
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
$prm = $this->sys_input;
|
}
|
||||||
$supplier = $prm["supplier"];
|
|
||||||
$search = $prm["search"];
|
|
||||||
$status = $prm["status"];
|
|
||||||
$startdate = $prm["startdate"];
|
|
||||||
$enddate = $prm["enddate"];
|
|
||||||
$regionalid = $this->sys_user['S_RegionalID'];
|
|
||||||
|
|
||||||
$number_limit = 10;
|
public function search_old()
|
||||||
$number_offset = ($prm['current_page'] - 1) * $number_limit ;
|
{
|
||||||
|
//# cek token valid
|
||||||
|
if (! $this->isLogin) {
|
||||||
|
$this->sys_error("Invalid Token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$where = "SupplierInvoiceIsActive = 'Y'
|
$prm = $this->sys_input;
|
||||||
AND SupplierInvoiceStatus = 'Approved'
|
$supplier = $prm["supplier"];
|
||||||
AND SupplierInvoiceGrandTotal > 0
|
$search = $prm["search"];
|
||||||
AND IF(SupplierPaymentID IS NULL,'N','Y') = '{$status}'
|
$status = $prm["status"];
|
||||||
AND (SupplierInvoiceNumber LIKE '%{$search}%' AND SupplierName LIKE '%{$supplier}%')
|
$startdate = $prm["startdate"];
|
||||||
AND ReceiveOrderPoS_RegionalID = {$regionalid}
|
$enddate = $prm["enddate"];
|
||||||
AND SupplierInvoiceDraftPaymentDate BETWEEN '{$startdate}' AND '{$enddate}'";
|
$regionalid = $this->sys_user['S_RegionalID'];
|
||||||
|
|
||||||
|
$number_limit = 10;
|
||||||
|
$number_offset = ($prm['current_page'] - 1) * $number_limit;
|
||||||
|
|
||||||
|
$where = "SupplierInvoiceIsActive = 'Y'
|
||||||
|
AND SupplierInvoiceStatus = 'Approved'
|
||||||
|
AND SupplierInvoiceGrandTotal > 0
|
||||||
|
AND IF(SupplierPaymentID IS NULL,'N','Y') = '{$status}'
|
||||||
|
AND (SupplierInvoiceNumber LIKE '%{$search}%' AND SupplierName LIKE '%{$supplier}%')
|
||||||
|
AND ReceiveOrderPoS_RegionalID = {$regionalid}
|
||||||
|
AND SupplierInvoiceDraftPaymentDate BETWEEN '{$startdate}' AND '{$enddate}'";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$sql = " SELECT count(*) as total
|
$sql = " SELECT count(*) as total
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
LEFT JOIN supplier_payment ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
LEFT JOIN supplier_payment ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
||||||
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
||||||
WHERE
|
WHERE
|
||||||
$where
|
$where
|
||||||
";
|
";
|
||||||
// echo $sql;
|
// echo $sql;
|
||||||
$query = $this->db_onedev->query($sql, $sql_param);
|
$query = $this->db_onedev->query($sql, $sql_param);
|
||||||
|
|
||||||
|
|
||||||
$tot_count = 0;
|
$tot_count = 0;
|
||||||
$tot_page = 0;
|
$tot_page = 0;
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$tot_count = $query->result_array()[0]["total"];
|
$tot_count = $query->result_array()[0]["total"];
|
||||||
$tot_page = ceil($tot_count/$number_limit);
|
$tot_page = ceil($tot_count / $number_limit);
|
||||||
} else {
|
} else {
|
||||||
$this->sys_error_db("supplier_invoice count", $this->db_onedev);
|
$this->sys_error_db("supplier_invoice count", $this->db_onedev);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$sql = "SELECT supplier_invoice.*,
|
$sql = "SELECT supplier_invoice.*,
|
||||||
SupplierName,
|
SupplierName,
|
||||||
'' M_MouName,
|
'' M_MouName,
|
||||||
0 as totalbill,
|
0 as totalbill,
|
||||||
0 as paid,
|
0 as paid,
|
||||||
0 as unpaid,
|
0 as unpaid,
|
||||||
SupplierInvoiceIsLunas as flaglunas,
|
SupplierInvoiceIsLunas as flaglunas,
|
||||||
0 as SupplierPaymentID,
|
0 as SupplierPaymentID,
|
||||||
'' as SupplierPaymentNumber,
|
'' as SupplierPaymentNumber,
|
||||||
0 as SupplierPaymentAmount,
|
0 as SupplierPaymentAmount,
|
||||||
'' as SupplierPaymentDate,
|
'' as SupplierPaymentDate,
|
||||||
'' as SupplierInvoiceIssueRefNumber,
|
'' as SupplierInvoiceIssueRefNumber,
|
||||||
'' as notes,
|
'' as notes,
|
||||||
'' as tagihans,
|
'' as tagihans,
|
||||||
'N' as isbillterpusat,
|
'N' as isbillterpusat,
|
||||||
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d-%m-%Y') as tanggalbayar,
|
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d-%m-%Y') as tanggalbayar,
|
||||||
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d%m%Y') as tanggalbayartext,
|
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d%m%Y') as tanggalbayartext,
|
||||||
IF(SupplierPaymentID IS NULL,'N','Y') as status_invoice,
|
IF(SupplierPaymentID IS NULL,'N','Y') as status_invoice,
|
||||||
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
||||||
IFNULL(SupplierPaymentIsVerif,'N') as SupplierPaymentIsVerif,
|
IFNULL(SupplierPaymentIsVerif,'N') as SupplierPaymentIsVerif,
|
||||||
IFNULL(SupplierPaymentCashierNumber,'') SupplierPaymentCashierNumber
|
IFNULL(SupplierPaymentCashierNumber,'') SupplierPaymentCashierNumber
|
||||||
|
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
||||||
LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
LEFT JOIN supplier_payment ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID AND SupplierPaymentIsActive = 'Y'
|
||||||
WHERE
|
WHERE
|
||||||
$where
|
$where
|
||||||
GROUP BY SupplierInvoiceID
|
GROUP BY SupplierInvoiceID
|
||||||
ORDER BY SupplierInvoiceID ASC
|
ORDER BY SupplierInvoiceID ASC
|
||||||
limit $number_limit offset $number_offset";
|
limit $number_limit offset $number_offset";
|
||||||
//echo $sql;
|
//echo $sql;
|
||||||
$query = $this->db_onedev->query($sql, $sql_param);
|
$query = $this->db_onedev->query($sql, $sql_param);
|
||||||
$rows = $query->result_array();
|
$rows = $query->result_array();
|
||||||
if($rows){
|
if ($rows) {
|
||||||
foreach($rows as $k => $v){
|
foreach ($rows as $k => $v) {
|
||||||
$s_payment = $this->db_onedev->query("SELECT GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
$s_payment = $this->db_onedev->query("SELECT GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
||||||
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
||||||
IFNULL(SupplierPaymentID,0) SupplierPaymentID,
|
IFNULL(SupplierPaymentID,0) SupplierPaymentID,
|
||||||
GROUP_CONCAT(DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y') SEPARATOR ', ') as SupplierPaymentDate
|
GROUP_CONCAT(DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y') SEPARATOR ', ') as SupplierPaymentDate
|
||||||
FROM supplier_payment
|
FROM supplier_payment
|
||||||
WHERE SupplierPaymentIsActive = 'Y' AND SupplierPaymentSupplierInvoiceID = {$v['SupplierInvoiceID']}")->row();
|
WHERE SupplierPaymentIsActive = 'Y' AND SupplierPaymentSupplierInvoiceID = {$v['SupplierInvoiceID']}")->row();
|
||||||
|
|
||||||
$s_jurnal = $this->db_onedev->query("SELECT SUM(jurnalTxCredit) totalbill
|
$s_jurnal = $this->db_onedev->query("SELECT SUM(jurnalTxCredit) totalbill
|
||||||
FROM supplier_invoice
|
FROM supplier_invoice
|
||||||
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563
|
JOIN jurnal_tx ON jurnalTxJurnalID = jurnalAddOnJurnalID AND jurnalTxCredit <> 0 AND jurnalTxCoaID <> 563
|
||||||
WHERE SupplierInvoiceID = {$v['SupplierInvoiceID']}
|
WHERE SupplierInvoiceID = {$v['SupplierInvoiceID']}
|
||||||
GROUP BY SupplierInvoiceID")->row();
|
GROUP BY SupplierInvoiceID")->row();
|
||||||
$amount = $s_payment->SupplierPaymentAmount ? $s_payment->SupplierPaymentAmount : "0.00";
|
$amount = $s_payment->SupplierPaymentAmount ? $s_payment->SupplierPaymentAmount : "0.00";
|
||||||
$unpaid = (float)$s_jurnal->totalbill - (float)$amount;
|
$unpaid = (float)$s_jurnal->totalbill - (float)$amount;
|
||||||
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID ? $s_payment->SupplierPaymentID : '0';
|
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID ? $s_payment->SupplierPaymentID : '0';
|
||||||
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber ? $s_payment->SupplierPaymentNumber : '';
|
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber ? $s_payment->SupplierPaymentNumber : '';
|
||||||
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
||||||
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
||||||
$rows[$k]['paid'] = $amount;
|
$rows[$k]['paid'] = $amount;
|
||||||
$rows[$k]['totalbill'] = $s_jurnal->totalbill ? $s_jurnal->totalbill : "0.00";
|
$rows[$k]['totalbill'] = $s_jurnal->totalbill ? $s_jurnal->totalbill : "0.00";
|
||||||
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
||||||
|
|
||||||
$rows[$k]['notes'] = $this->add_notes($v['SupplierInvoiceID']);
|
$rows[$k]['notes'] = $this->add_notes($v['SupplierInvoiceID']);
|
||||||
$rows[$k]['tagihans'] = $this->add_tagihans($v['SupplierInvoiceID']);
|
$rows[$k]['tagihans'] = $this->add_tagihans($v['SupplierInvoiceID']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$result = array("total" => $tot_page, "records" => $rows, "sql"=> $this->db_onedev->last_query());
|
$result = array("total" => $tot_page, "records" => $rows, "sql" => $this->db_onedev->last_query());
|
||||||
$this->sys_ok($result);
|
$this->sys_ok($result);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search — unified invoice + downpayment list:
|
||||||
|
* - Only columns the frontend actually reads (no wildcard, no dead aliases)
|
||||||
|
* - UNION ALL merges supplier_invoice and supplier_downpayment
|
||||||
|
* - DP rows enriched via SupplierPaymentSupplierDownpaymentID FK
|
||||||
|
* - All queries use PDO parameterised placeholders
|
||||||
|
*/
|
||||||
|
public function search()
|
||||||
|
{
|
||||||
|
if (! $this->isLogin) {
|
||||||
|
$this->sys_error("Invalid Token");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$prm = $this->sys_input;
|
||||||
|
$supplier = $prm["supplier"];
|
||||||
|
$search = $prm["search"];
|
||||||
|
$status = $prm["status"];
|
||||||
|
$startdate = $prm["startdate"];
|
||||||
|
$enddate = $prm["enddate"];
|
||||||
|
$regionalid = $this->sys_user['S_RegionalID'];
|
||||||
|
|
||||||
|
$number_limit = 10;
|
||||||
|
$number_offset = ((int)$prm['current_page'] - 1) * $number_limit;
|
||||||
|
|
||||||
|
// ── INVOICE WHERE ──────────────────────────────────────────
|
||||||
|
$inv_where = " SupplierInvoiceIsActive = 'Y'
|
||||||
|
AND SupplierInvoiceStatus = 'Approved'
|
||||||
|
AND SupplierInvoiceGrandTotal > 0
|
||||||
|
AND SupplierInvoiceIsInstallment = 'N'
|
||||||
|
AND IF(SupplierPaymentID IS NULL,'N','Y') = ?
|
||||||
|
AND SupplierInvoiceNumber LIKE ?
|
||||||
|
AND SupplierName LIKE ?
|
||||||
|
AND ReceiveOrderPoS_RegionalID = ?
|
||||||
|
AND SupplierInvoiceDraftPaymentDate BETWEEN ? AND ? ";
|
||||||
|
|
||||||
|
$inv_params = [
|
||||||
|
$status,
|
||||||
|
'%' . $search . '%',
|
||||||
|
'%' . $supplier . '%',
|
||||||
|
$regionalid,
|
||||||
|
$startdate,
|
||||||
|
$enddate,
|
||||||
|
];
|
||||||
|
|
||||||
|
// ── DOWNPAYMENT WHERE ──────────────────────────────────────
|
||||||
|
$dp_where = " SupplierDownpaymentIsActive = 'Y'
|
||||||
|
AND IF(SupplierDownpaymentStatus = 'Paid','Y','N') = ?
|
||||||
|
AND PurchaseOrderNumber LIKE ?
|
||||||
|
AND SupplierName LIKE ?
|
||||||
|
AND PurchaseOrderS_RegionalID = ?
|
||||||
|
AND SupplierDownpaymentDueDate BETWEEN ? AND ? ";
|
||||||
|
|
||||||
|
$dp_params = [
|
||||||
|
$status,
|
||||||
|
'%' . $search . '%',
|
||||||
|
'%' . $supplier . '%',
|
||||||
|
$regionalid,
|
||||||
|
$startdate,
|
||||||
|
$enddate,
|
||||||
|
];
|
||||||
|
|
||||||
|
// ── INSTALLMENT WHERE ───────────────────────────────────
|
||||||
|
$inst_where = " inst.SupplierInstallmentIsActive = 'Y'
|
||||||
|
AND IF(sp.SupplierPaymentID IS NULL,'N','Y') = ?
|
||||||
|
AND CONCAT('INST-', si.SupplierInvoiceNumber) LIKE ?
|
||||||
|
AND sup.SupplierName LIKE ?
|
||||||
|
AND rop.ReceiveOrderPoS_RegionalID = ?
|
||||||
|
AND inst.SupplierInstallmentDueDate BETWEEN ? AND ? ";
|
||||||
|
|
||||||
|
$inst_params = [
|
||||||
|
$status,
|
||||||
|
'%' . $search . '%',
|
||||||
|
'%' . $supplier . '%',
|
||||||
|
$regionalid,
|
||||||
|
$startdate,
|
||||||
|
$enddate,
|
||||||
|
];
|
||||||
|
|
||||||
|
// ── COUNT query — UNION of all three sources ────────────
|
||||||
|
$sql_count = "SELECT SUM(cnt) as total FROM (
|
||||||
|
SELECT count(*) as cnt
|
||||||
|
FROM supplier_invoice
|
||||||
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
|
LEFT JOIN supplier_payment
|
||||||
|
ON SupplierInvoiceID = SupplierPaymentSupplierInvoiceID
|
||||||
|
AND SupplierPaymentIsActive = 'Y'
|
||||||
|
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
|
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
||||||
|
WHERE $inv_where
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT count(*) as cnt
|
||||||
|
FROM supplier_downpayment
|
||||||
|
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
||||||
|
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
||||||
|
WHERE $dp_where
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT count(*) as cnt
|
||||||
|
FROM supplier_installment inst
|
||||||
|
LEFT JOIN supplier_payment sp
|
||||||
|
ON sp.SupplierPaymentSupplierInstallmentID = inst.SupplierInstallmentID
|
||||||
|
AND sp.SupplierPaymentIsActive = 'Y'
|
||||||
|
JOIN supplier_invoice si
|
||||||
|
ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
||||||
|
JOIN receive_order_po rop
|
||||||
|
ON rop.ReceiveOrderPoID = si.SupplierInvoiceReceiveOrderPoID
|
||||||
|
JOIN supplier sup
|
||||||
|
ON sup.SupplierID = inst.SupplierInstallmentSupplierID
|
||||||
|
WHERE $inst_where
|
||||||
|
) AS combined";
|
||||||
|
|
||||||
|
$count_params = array_merge($inv_params, $dp_params, $inst_params);
|
||||||
|
$query = $this->db_onedev->query($sql_count, $count_params);
|
||||||
|
|
||||||
|
$tot_count = 0;
|
||||||
|
$tot_page = 0;
|
||||||
|
if ($query) {
|
||||||
|
$tot_count = $query->result_array()[0]["total"];
|
||||||
|
$tot_page = ceil($tot_count / $number_limit);
|
||||||
|
} else {
|
||||||
|
$this->sys_error_db("payment instructions count", $this->db_onedev);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── DATA query — UNION with identical columns ──────────────
|
||||||
|
$sql_data = "
|
||||||
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
SupplierInvoiceID,
|
||||||
|
0 as DownpaymentID,
|
||||||
|
0 as InstallmentID,
|
||||||
|
SupplierInvoiceNumber,
|
||||||
|
SupplierInvoiceDraftPaymentDate,
|
||||||
|
SupplierInvoiceIsLunas as flaglunas,
|
||||||
|
SupplierName,
|
||||||
|
DATE_FORMAT(SupplierInvoiceDraftPaymentDate,'%d-%m-%Y') as tanggalbayar,
|
||||||
|
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
||||||
|
IFNULL(SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber,
|
||||||
|
0 as totalbill,
|
||||||
|
0 as paid,
|
||||||
|
0 as unpaid,
|
||||||
|
0 as SupplierPaymentID,
|
||||||
|
'' as SupplierPaymentNumber,
|
||||||
|
0 as SupplierPaymentAmount,
|
||||||
|
'' as SupplierPaymentDate,
|
||||||
|
'' as notes,
|
||||||
|
'' as tagihans,
|
||||||
|
0 as parent_invoice_id,
|
||||||
|
'INVOICE' as type
|
||||||
|
FROM supplier_invoice
|
||||||
|
LEFT JOIN supplier ON SupplierInvoiceSupplierID = SupplierID
|
||||||
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
|
JOIN receive_order_po ON SupplierInvoiceReceiveOrderPoID = ReceiveOrderPoID
|
||||||
|
LEFT JOIN supplier_payment
|
||||||
|
ON SupplierPaymentSupplierInvoiceID = SupplierInvoiceID
|
||||||
|
AND SupplierPaymentIsActive = 'Y'
|
||||||
|
WHERE $inv_where
|
||||||
|
GROUP BY SupplierInvoiceID
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
0 as SupplierInvoiceID,
|
||||||
|
SupplierDownpaymentID as DownpaymentID,
|
||||||
|
0 as InstallmentID,
|
||||||
|
CONCAT('DP-', PurchaseOrderNumber) as SupplierInvoiceNumber,
|
||||||
|
SupplierDownpaymentDueDate as SupplierInvoiceDraftPaymentDate,
|
||||||
|
SupplierDownpaymentIsLunas as flaglunas,
|
||||||
|
SupplierName,
|
||||||
|
DATE_FORMAT(SupplierDownpaymentDueDate,'%d-%m-%Y') as tanggalbayar,
|
||||||
|
IFNULL(SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
||||||
|
IFNULL(SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber,
|
||||||
|
SupplierDownpaymentAmount as totalbill,
|
||||||
|
CASE WHEN SupplierDownpaymentStatus = 'Paid'
|
||||||
|
THEN SupplierDownpaymentAmount
|
||||||
|
ELSE 0 END as paid,
|
||||||
|
CASE WHEN SupplierDownpaymentStatus = 'Paid'
|
||||||
|
THEN 0
|
||||||
|
ELSE SupplierDownpaymentAmount END as unpaid,
|
||||||
|
0 as SupplierPaymentID,
|
||||||
|
'' as SupplierPaymentNumber,
|
||||||
|
0 as SupplierPaymentAmount,
|
||||||
|
'' as SupplierPaymentDate,
|
||||||
|
'' as notes,
|
||||||
|
'' as tagihans,
|
||||||
|
0 as parent_invoice_id,
|
||||||
|
'DP' as type
|
||||||
|
FROM supplier_downpayment
|
||||||
|
JOIN purchase_order ON PurchaseOrderID = SupplierDownpaymentPurchasOrderID
|
||||||
|
JOIN supplier ON SupplierID = SupplierDownpaymentSupplierID
|
||||||
|
LEFT JOIN supplier_payment
|
||||||
|
ON SupplierPaymentSupplierDownpaymentID = SupplierDownpaymentID
|
||||||
|
AND SupplierPaymentIsActive = 'Y'
|
||||||
|
WHERE $dp_where
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
0 as SupplierInvoiceID,
|
||||||
|
0 as DownpaymentID,
|
||||||
|
inst.SupplierInstallmentID as InstallmentID,
|
||||||
|
CONCAT('INST-', si.SupplierInvoiceNumber) as SupplierInvoiceNumber,
|
||||||
|
inst.SupplierInstallmentDueDate as SupplierInvoiceDraftPaymentDate,
|
||||||
|
inst.SupplierInstallmentIsLunas as flaglunas,
|
||||||
|
sup.SupplierName,
|
||||||
|
DATE_FORMAT(inst.SupplierInstallmentDueDate,'%d-%m-%Y') as tanggalbayar,
|
||||||
|
IFNULL(sp.SupplierPaymentIsApproved,'N') as SupplierPaymentIsApproved,
|
||||||
|
IFNULL(sp.SupplierPaymentCashierNumber,'') as SupplierPaymentCashierNumber,
|
||||||
|
inst.SupplierInstallmentAmount as totalbill,
|
||||||
|
CASE WHEN inst.SupplierInstallmentStatus = 'Paid'
|
||||||
|
THEN inst.SupplierInstallmentAmount
|
||||||
|
ELSE 0 END as paid,
|
||||||
|
CASE WHEN inst.SupplierInstallmentStatus = 'Paid'
|
||||||
|
THEN 0
|
||||||
|
ELSE inst.SupplierInstallmentAmount END as unpaid,
|
||||||
|
0 as SupplierPaymentID,
|
||||||
|
'' as SupplierPaymentNumber,
|
||||||
|
0 as SupplierPaymentAmount,
|
||||||
|
'' as SupplierPaymentDate,
|
||||||
|
'' as notes,
|
||||||
|
'' as tagihans,
|
||||||
|
si.SupplierInvoiceID as parent_invoice_id,
|
||||||
|
'INSTALLMENT' as type
|
||||||
|
FROM supplier_installment inst
|
||||||
|
LEFT JOIN supplier_payment sp
|
||||||
|
ON sp.SupplierPaymentSupplierInstallmentID = inst.SupplierInstallmentID
|
||||||
|
AND sp.SupplierPaymentIsActive = 'Y'
|
||||||
|
JOIN supplier_invoice si
|
||||||
|
ON si.SupplierInvoiceID = inst.SupplierInstallmentSupplierInvoiceID
|
||||||
|
JOIN receive_order_po rop
|
||||||
|
ON rop.ReceiveOrderPoID = si.SupplierInvoiceReceiveOrderPoID
|
||||||
|
JOIN supplier sup
|
||||||
|
ON sup.SupplierID = inst.SupplierInstallmentSupplierID
|
||||||
|
WHERE $inst_where
|
||||||
|
) AS combined
|
||||||
|
ORDER BY SupplierInvoiceID ASC
|
||||||
|
LIMIT ? OFFSET ?";
|
||||||
|
|
||||||
|
$data_params = array_merge($inv_params, $dp_params, $inst_params, [$number_limit, $number_offset]);
|
||||||
|
$query = $this->db_onedev->query($sql_data, $data_params);
|
||||||
|
if (!$query) {
|
||||||
|
$this->sys_error_db("payment instructions data", $this->db_onedev);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$rows = $query->result_array();
|
||||||
|
|
||||||
|
// ── ENRICH — per-row sub-queries ───────────────────────────
|
||||||
|
if ($rows) {
|
||||||
|
foreach ($rows as $k => $v) {
|
||||||
|
|
||||||
|
// ── Downpayment branch ──────────────────────────
|
||||||
|
if ($v['type'] === 'DP') {
|
||||||
|
$dp_id = $v['DownpaymentID'];
|
||||||
|
|
||||||
|
$s_payment = $this->db_onedev->query("
|
||||||
|
SELECT
|
||||||
|
GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
||||||
|
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
||||||
|
IFNULL(SupplierPaymentID,0) as SupplierPaymentID,
|
||||||
|
GROUP_CONCAT(
|
||||||
|
DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y')
|
||||||
|
SEPARATOR ', '
|
||||||
|
) as SupplierPaymentDate
|
||||||
|
FROM supplier_payment
|
||||||
|
WHERE SupplierPaymentIsActive = 'Y'
|
||||||
|
AND SupplierPaymentSupplierDownpaymentID = ?",
|
||||||
|
[$dp_id]
|
||||||
|
)->row();
|
||||||
|
|
||||||
|
$amount = $s_payment->SupplierPaymentAmount
|
||||||
|
? $s_payment->SupplierPaymentAmount
|
||||||
|
: "0.00";
|
||||||
|
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID
|
||||||
|
? $s_payment->SupplierPaymentID
|
||||||
|
: '0';
|
||||||
|
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber
|
||||||
|
? $s_payment->SupplierPaymentNumber
|
||||||
|
: '';
|
||||||
|
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
||||||
|
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
||||||
|
$rows[$k]['paid'] = $amount;
|
||||||
|
$rows[$k]['notes'] = $this->add_notes_downpayment($dp_id);
|
||||||
|
$rows[$k]['tagihans'] = [];
|
||||||
|
// totalbill, unpaid already correct from UNION CASE
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Installment branch ─────────────────────────
|
||||||
|
if ($v['type'] === 'INSTALLMENT') {
|
||||||
|
$inst_id = $v['InstallmentID'];
|
||||||
|
$parent_invoice_id = $v['parent_invoice_id'];
|
||||||
|
|
||||||
|
$s_payment = $this->db_onedev->query("
|
||||||
|
SELECT
|
||||||
|
GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
||||||
|
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
||||||
|
IFNULL(SupplierPaymentID,0) as SupplierPaymentID,
|
||||||
|
GROUP_CONCAT(
|
||||||
|
DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y')
|
||||||
|
SEPARATOR ', '
|
||||||
|
) as SupplierPaymentDate
|
||||||
|
FROM supplier_payment
|
||||||
|
WHERE SupplierPaymentIsActive = 'Y'
|
||||||
|
AND SupplierPaymentSupplierInstallmentID = ?",
|
||||||
|
[$inst_id]
|
||||||
|
)->row();
|
||||||
|
|
||||||
|
$amount = $s_payment->SupplierPaymentAmount
|
||||||
|
? $s_payment->SupplierPaymentAmount
|
||||||
|
: "0.00";
|
||||||
|
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID
|
||||||
|
? $s_payment->SupplierPaymentID
|
||||||
|
: '0';
|
||||||
|
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber
|
||||||
|
? $s_payment->SupplierPaymentNumber
|
||||||
|
: '';
|
||||||
|
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
||||||
|
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
||||||
|
$rows[$k]['paid'] = $amount;
|
||||||
|
$rows[$k]['notes'] = $this->add_notes_installment($inst_id);
|
||||||
|
$rows[$k]['tagihans'] = $this->add_tagihans($parent_invoice_id);
|
||||||
|
// totalbill, unpaid already correct from UNION CASE
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Invoice branch ───────────────────────────────
|
||||||
|
$inv_id = $v['SupplierInvoiceID'];
|
||||||
|
|
||||||
|
$s_payment = $this->db_onedev->query("
|
||||||
|
SELECT
|
||||||
|
GROUP_CONCAT(SupplierPaymentNumber SEPARATOR ', ') as SupplierPaymentNumber,
|
||||||
|
SUM(IFNULL(SupplierPaymentAmount,0)) as SupplierPaymentAmount,
|
||||||
|
IFNULL(SupplierPaymentID,0) as SupplierPaymentID,
|
||||||
|
GROUP_CONCAT(
|
||||||
|
DATE_FORMAT(SupplierPaymentDate,'%d-%m-%Y')
|
||||||
|
SEPARATOR ', '
|
||||||
|
) as SupplierPaymentDate
|
||||||
|
FROM supplier_payment
|
||||||
|
WHERE SupplierPaymentIsActive = 'Y'
|
||||||
|
AND SupplierPaymentSupplierInvoiceID = ?",
|
||||||
|
[$inv_id]
|
||||||
|
)->row();
|
||||||
|
|
||||||
|
$s_jurnal = $this->db_onedev->query("
|
||||||
|
SELECT SUM(jurnalTxCredit) totalbill
|
||||||
|
FROM supplier_invoice
|
||||||
|
JOIN jurnal_addon ON jurnalAddOnValue = SupplierInvoiceNumber
|
||||||
|
JOIN jurnal_tx
|
||||||
|
ON jurnalTxJurnalID = jurnalAddOnJurnalID
|
||||||
|
AND jurnalTxCredit <> 0
|
||||||
|
AND jurnalTxCoaID <> 563
|
||||||
|
WHERE SupplierInvoiceID = ?
|
||||||
|
GROUP BY SupplierInvoiceID",
|
||||||
|
[$inv_id]
|
||||||
|
)->row();
|
||||||
|
|
||||||
|
$amount = $s_payment->SupplierPaymentAmount
|
||||||
|
? $s_payment->SupplierPaymentAmount
|
||||||
|
: "0.00";
|
||||||
|
$unpaid = (float)$s_jurnal->totalbill - (float)$amount;
|
||||||
|
|
||||||
|
$rows[$k]['SupplierPaymentID'] = $s_payment->SupplierPaymentID
|
||||||
|
? $s_payment->SupplierPaymentID
|
||||||
|
: '0';
|
||||||
|
$rows[$k]['SupplierPaymentNumber'] = $s_payment->SupplierPaymentNumber
|
||||||
|
? $s_payment->SupplierPaymentNumber
|
||||||
|
: '';
|
||||||
|
$rows[$k]['SupplierPaymentAmount'] = $amount;
|
||||||
|
$rows[$k]['SupplierPaymentDate'] = $s_payment->SupplierPaymentDate;
|
||||||
|
$rows[$k]['paid'] = $amount;
|
||||||
|
$rows[$k]['totalbill'] = $s_jurnal->totalbill
|
||||||
|
? $s_jurnal->totalbill
|
||||||
|
: "0.00";
|
||||||
|
$rows[$k]['unpaid'] = number_format($unpaid, 2, '.', '');
|
||||||
|
|
||||||
|
$rows[$k]['notes'] = $this->add_notes($inv_id);
|
||||||
|
$rows[$k]['tagihans'] = $this->add_tagihans($inv_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array("total" => $tot_page, "records" => $rows);
|
||||||
|
$this->sys_ok($result);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
532
application/controllers/report/Rpt_faktur.php
Normal file
532
application/controllers/report/Rpt_faktur.php
Normal file
@@ -0,0 +1,532 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class FakturFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
||||||
|
|
||||||
|
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_faktur extends MY_Controller
|
||||||
|
{
|
||||||
|
// -- Properti bersama antar fungsi PDF -------------------------------------
|
||||||
|
/** @var FakturFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Faktur (Supplier Invoice) Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (SupplierInvoiceID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Ambil data header & detail dari DB ----------------------------
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// -- Inisialisasi FPDF custom --------------------------------------
|
||||||
|
$this->_pdf = new FakturFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// -- Susun isi halaman ---------------------------------------------
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_summary();
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// -- Output --------------------------------------------------------
|
||||||
|
$filename = 'INV_' . str_replace('/', '-', $header['SupplierInvoiceNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
si.*,
|
||||||
|
sup.SupplierName,
|
||||||
|
sup.SupplierAddress,
|
||||||
|
sup.SupplierPhone,
|
||||||
|
IFNULL(uCr.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(uVe.M_UserUsername, '') AS VerifiedByName,
|
||||||
|
IFNULL(uAp.M_UserUsername, '') AS ApprovedByName,
|
||||||
|
IFNULL(uPa.M_UserUsername, '') AS PaidByName,
|
||||||
|
IFNULL(uRe.M_UserUsername, '') AS ReceivedByName
|
||||||
|
FROM supplier_invoice si
|
||||||
|
LEFT JOIN supplier sup ON sup.SupplierID = si.SupplierInvoiceSupplierID
|
||||||
|
AND sup.SupplierIsActive = 'Y'
|
||||||
|
LEFT JOIN m_user uCr ON uCr.M_UserID = si.SupplierInvoiceCreatedUserID
|
||||||
|
LEFT JOIN m_user uVe ON uVe.M_UserID = si.SupplierInvoiceVerifiedUserID
|
||||||
|
LEFT JOIN m_user uAp ON uAp.M_UserID = si.SupplierInvoiceApprovedUserID
|
||||||
|
LEFT JOIN m_user uPa ON uPa.M_UserID = si.SupplierInvoicePaidUserID
|
||||||
|
LEFT JOIN m_user uRe ON uRe.M_UserID = si.SupplierInvoiceReceivedBy
|
||||||
|
WHERE si.SupplierInvoiceID = ?
|
||||||
|
AND si.SupplierInvoiceIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Faktur tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
sid.*,
|
||||||
|
i.M_ItemCode,
|
||||||
|
i.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM supplier_invoice_detail sid
|
||||||
|
LEFT JOIN m_item i ON i.M_ItemID = sid.SupplierInvoiceDetailItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = sid.SupplierInvoiceDetailItemUnitID
|
||||||
|
WHERE sid.SupplierInvoiceDetailSupplierInvoiceID = ?
|
||||||
|
AND sid.SupplierInvoiceDetailIsActive = 'Y'
|
||||||
|
ORDER BY sid.SupplierInvoiceDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// -- Judul utama --------------------------------------------------------
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'FAKTUR (SUPPLIER INVOICE)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 32;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// -- Kolom Kiri -----------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor Faktur', $header['SupplierInvoiceNumber'], true),
|
||||||
|
array('Tgl Faktur', $this->_fmt_date($header['SupplierInvoiceDate']), false),
|
||||||
|
array('Tgl Jatuh Tempo', $this->_fmt_date($header['SupplierInvoiceDueDate']), false),
|
||||||
|
array('Status', $header['SupplierInvoiceStatus'], false),
|
||||||
|
array('Supplier', $header['SupplierName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alamat Supplier (MultiCell)
|
||||||
|
if (!empty($header['SupplierAddress'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Alamat Supplier', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->MultiCell($valW, 4, $header['SupplierAddress'], 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan
|
||||||
|
if (!empty($header['SupplierInvoiceNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->MultiCell($valW, 4, $header['SupplierInvoiceNote'], 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// -- Kolom Kanan ----------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
// No. Supplier Invoice & tgl (jika ada)
|
||||||
|
$rightItems = array();
|
||||||
|
if (!empty($header['SupplierInvoiceSupplierInvoiceNumber'])) {
|
||||||
|
$rightItems[] = array('No. Inv. Supplier', $header['SupplierInvoiceSupplierInvoiceNumber']);
|
||||||
|
$rightItems[] = array('Tgl Inv. Supplier', $this->_fmt_date($header['SupplierInvoiceSupplierInvoiceDate']));
|
||||||
|
}
|
||||||
|
$rightItems[] = array('No. Delivery Order', $header['SupplierInvoiceDeliveryOrderNumber'] ?: '-');
|
||||||
|
$rightItems[] = array('Dibuat Oleh', $header['CreatedByName'] ?: '-');
|
||||||
|
$rightItems[] = array('Dibuat Tgl', $this->_fmt_datetime($header['SupplierInvoiceCreated']));
|
||||||
|
|
||||||
|
if ($header['SupplierInvoiceStatus'] === 'Verified' || in_array($header['SupplierInvoiceStatus'], ['Approved', 'Scheduled', 'Paid', 'Partially Paid'])) {
|
||||||
|
if (!empty($header['SupplierInvoiceVerifiedDate'])) {
|
||||||
|
$rightItems[] = array('Diverifikasi Oleh', $header['VerifiedByName'] ?: '-');
|
||||||
|
$rightItems[] = array('Tgl Verifikasi', $this->_fmt_datetime($header['SupplierInvoiceVerifiedDate']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($header['SupplierInvoiceStatus'], ['Approved', 'Scheduled', 'Paid', 'Partially Paid'])) {
|
||||||
|
if (!empty($header['SupplierInvoiceApprovedDate'])) {
|
||||||
|
$rightItems[] = array('Disetujui Oleh', $header['ApprovedByName'] ?: '-');
|
||||||
|
$rightItems[] = array('Tgl Disetujui', $this->_fmt_datetime($header['SupplierInvoiceApprovedDate']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($header['SupplierInvoiceStatus'] === 'Paid' || $header['SupplierInvoiceStatus'] === 'Partially Paid') {
|
||||||
|
if (!empty($header['SupplierInvoicePaidDate'])) {
|
||||||
|
$rightItems[] = array('Dibayar Oleh', $header['PaidByName'] ?: '-');
|
||||||
|
$rightItems[] = array('Tgl Dibayar', $this->_fmt_datetime($header['SupplierInvoicePaidDate']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tgl Terima & Penerima (jika ada)
|
||||||
|
if (!empty($header['SupplierInvoiceReceiveDate'])) {
|
||||||
|
$rightItems[] = array('Tgl Terima', $this->_fmt_date($header['SupplierInvoiceReceiveDate']));
|
||||||
|
$rightItems[] = array('Diterima Oleh', $header['ReceivedByName'] ?: '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
// -- Definisi kolom: [label, lebar, align] -------------------------------
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 62 + 15 + 20 + 25 + 25 + 25 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Deskripsi', 62, 'L'),
|
||||||
|
array('Unit', 15, 'C'),
|
||||||
|
array('Qty', 20, 'R'),
|
||||||
|
array('Harga Satuan', 25, 'R'),
|
||||||
|
array('Diskon', 25, 'R'),
|
||||||
|
array('Total', 25, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 7.5);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$qty = floatval($d['SupplierInvoiceDetailQty'] ?? 0);
|
||||||
|
$price = floatval($d['SupplierInvoiceDetailPrice'] ?? 0);
|
||||||
|
$discAmount = floatval($d['SupplierInvoiceDetailDiscountAmount'] ?? 0);
|
||||||
|
$total = floatval($d['SupplierInvoiceDetailTotal'] ?? 0);
|
||||||
|
$desc = $d['SupplierInvoiceDetailDescription'] ?: ($d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'));
|
||||||
|
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $desc, 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'),1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($price), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $discAmount > 0 ? $this->_fmt_rp($discAmount) : '-', 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($total), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Ringkasan Nilai (SubTotal, Pajak, Grand Total)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_summary()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// -- Ringkasan nilai (rata kanan) ----------------------------------------
|
||||||
|
$cW1 = 50;
|
||||||
|
$cW2 = 40;
|
||||||
|
$offsetX = 15 + $this->_pageW - $cW1 - $cW2;
|
||||||
|
|
||||||
|
// Garis pemisah
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->Line(15 + $pageW - $cW1 - $cW2 - 4, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$items = array();
|
||||||
|
|
||||||
|
// Sub Total
|
||||||
|
$items[] = array('Sub Total', $this->_fmt_rp($header['SupplierInvoiceSubTotal']));
|
||||||
|
|
||||||
|
// Diskon (jika ada)
|
||||||
|
$discPct = floatval($header['SupplierInvoiceDiscountPercent'] ?? 0);
|
||||||
|
$discAmt = floatval($header['SupplierInvoiceDiscountAmount'] ?? 0);
|
||||||
|
if ($discPct > 0 || $discAmt > 0) {
|
||||||
|
$label = 'Diskon';
|
||||||
|
if ($discPct > 0) $label .= ' (' . $this->_fmt_num($discPct) . '%)';
|
||||||
|
$items[] = array($label, $this->_fmt_rp($discAmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPh (jika ada)
|
||||||
|
$pphPct = floatval($header['SupplierInvoiceTaxPercentPph'] ?? 0);
|
||||||
|
$pphAmt = floatval($header['SupplierInvoiceTaxAmountPph'] ?? 0);
|
||||||
|
if ($pphPct > 0 || $pphAmt > 0) {
|
||||||
|
$label = 'PPh';
|
||||||
|
if ($pphPct > 0) $label .= ' (' . $this->_fmt_num($pphPct) . '%)';
|
||||||
|
$items[] = array($label, $this->_fmt_rp($pphAmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPN (jika ada)
|
||||||
|
$ppnPct = floatval($header['SupplierInvoiceTaxPercentPpn'] ?? 0);
|
||||||
|
$ppnAmt = floatval($header['SupplierInvoiceTaxAmountPpn'] ?? 0);
|
||||||
|
if ($ppnPct > 0 || $ppnAmt > 0) {
|
||||||
|
$label = 'PPN';
|
||||||
|
if ($ppnPct > 0) $label .= ' (' . $this->_fmt_num($ppnPct) . '%)';
|
||||||
|
$items[] = array($label, $this->_fmt_rp($ppnAmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Biaya Kirim (jika ada)
|
||||||
|
$shipCost = floatval($header['SupplierInvoiceShippingCost'] ?? 0);
|
||||||
|
if ($shipCost > 0) {
|
||||||
|
$items[] = array('Biaya Kirim', $this->_fmt_rp($shipCost));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Penyesuaian (jika ada)
|
||||||
|
$adjAmt = floatval($header['SupplierInvoiceAdjustmentAmount'] ?? 0);
|
||||||
|
if ($adjAmt != 0) {
|
||||||
|
$label = 'Penyesuaian';
|
||||||
|
if (!empty($header['SupplierInvoiceAdjustmentNote'])) {
|
||||||
|
$label .= ' (' . $header['SupplierInvoiceAdjustmentNote'] . ')';
|
||||||
|
}
|
||||||
|
$items[] = array($label, $this->_fmt_rp($adjAmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $item[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grand Total (tebal)
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->Line($offsetX, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(1);
|
||||||
|
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
||||||
|
$pdf->Cell($cW1, 6, 'Grand Total', 0, 0, 'L');
|
||||||
|
$pdf->Cell($cW2, 6, $this->_fmt_rp($header['SupplierInvoiceGrandTotal']), 0, 1, 'R');
|
||||||
|
|
||||||
|
// Sudah dibayar / sisa
|
||||||
|
$paidAmt = floatval($header['SupplierInvoicePaidAmount'] ?? 0);
|
||||||
|
$unpaidAmt = floatval($header['SupplierInvoiceUnpaid'] ?? 0);
|
||||||
|
$isLunas = $header['SupplierInvoiceIsLunas'] ?? 'N';
|
||||||
|
|
||||||
|
if ($paidAmt > 0) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, 'Dibayar', 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $this->_fmt_rp($paidAmt), 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isLunas === 'Y') {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->SetTextColor(0, 128, 0);
|
||||||
|
$pdf->Cell($cW1 + $cW2, 5, 'LUNAS', 0, 1, 'R');
|
||||||
|
$pdf->SetTextColor(0, 0, 0);
|
||||||
|
} elseif ($unpaidAmt > 0) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW1, 5, 'Sisa Tagihan', 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $this->_fmt_rp($unpaidAmt), 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Faktur ini diterbitkan berdasarkan barang/jasa yang telah diterima dan sesuai dengan purchase order.',
|
||||||
|
'Pembayaran harus dilakukan sesuai dengan tanggal jatuh tempo yang tercantum.',
|
||||||
|
'Keterlambatan pembayaran akan dikenakan sanksi sesuai ketentuan yang berlaku.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan administrasi perusahaan.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
512
application/controllers/report/Rpt_payment_voucher.php
Normal file
512
application/controllers/report/Rpt_payment_voucher.php
Normal file
@@ -0,0 +1,512 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class PaymentVoucherFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Properties untuk tabel multiline
|
||||||
|
public $widths;
|
||||||
|
public $aligns;
|
||||||
|
|
||||||
|
public function SetWidths($w)
|
||||||
|
{
|
||||||
|
$this->widths = $w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetAligns($a)
|
||||||
|
{
|
||||||
|
$this->aligns = $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Row($data, $fill = false, $h = 6)
|
||||||
|
{
|
||||||
|
// Hitung tinggi maksimum baris berdasarkan multiline
|
||||||
|
$nb = 0;
|
||||||
|
for ($i = 0; $i < count($data); $i++) {
|
||||||
|
$nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
|
||||||
|
}
|
||||||
|
$rowH = $h * $nb;
|
||||||
|
|
||||||
|
// Cek apakah perlu ganti halaman secara otomatis
|
||||||
|
$this->CheckPageBreak($rowH);
|
||||||
|
|
||||||
|
// Gambar cell pada baris
|
||||||
|
for ($i = 0; $i < count($data); $i++) {
|
||||||
|
$w = $this->widths[$i];
|
||||||
|
$a = isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
|
||||||
|
|
||||||
|
$x = $this->GetX();
|
||||||
|
$y = $this->GetY();
|
||||||
|
|
||||||
|
// Gambar border dan background
|
||||||
|
$this->Rect($x, $y, $w, $rowH, $fill ? 'DF' : 'D');
|
||||||
|
// Tulis teks menggunakan MultiCell
|
||||||
|
$this->MultiCell($w, $h, $data[$i], 0, $a);
|
||||||
|
// Geser posisi X ke kanan untuk cell berikutnya
|
||||||
|
$this->SetXY($x + $w, $y);
|
||||||
|
}
|
||||||
|
// Pindah baris
|
||||||
|
$this->Ln($rowH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CheckPageBreak($h)
|
||||||
|
{
|
||||||
|
// Jika tinggi baris melewati batas, buat halaman baru
|
||||||
|
if ($this->GetY() + $h > $this->PageBreakTrigger) {
|
||||||
|
$this->AddPage($this->CurOrientation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function NbLines($w, $txt)
|
||||||
|
{
|
||||||
|
// Menghitung jumlah baris yang akan dihasilkan oleh MultiCell
|
||||||
|
$cw =& $this->CurrentFont['cw'];
|
||||||
|
if ($w == 0) {
|
||||||
|
$w = $this->w - $this->rMargin - $this->x;
|
||||||
|
}
|
||||||
|
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
|
||||||
|
$s = str_replace("\r", '', $txt);
|
||||||
|
$nb = strlen($s);
|
||||||
|
if ($nb > 0 && $s[$nb - 1] == "\n") {
|
||||||
|
$nb--;
|
||||||
|
}
|
||||||
|
$sep = -1;
|
||||||
|
$i = 0;
|
||||||
|
$j = 0;
|
||||||
|
$l = 0;
|
||||||
|
$nl = 1;
|
||||||
|
while ($i < $nb) {
|
||||||
|
$c = $s[$i];
|
||||||
|
if ($c == "\n") {
|
||||||
|
$i++;
|
||||||
|
$sep = -1;
|
||||||
|
$j = $i;
|
||||||
|
$l = 0;
|
||||||
|
$nl++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($c == ' ') {
|
||||||
|
$sep = $i;
|
||||||
|
}
|
||||||
|
$l += $cw[$c];
|
||||||
|
if ($l > $wmax) {
|
||||||
|
if ($sep == -1) {
|
||||||
|
if ($i == $j) {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$i = $sep + 1;
|
||||||
|
}
|
||||||
|
$sep = -1;
|
||||||
|
$j = $i;
|
||||||
|
$l = 0;
|
||||||
|
$nl++;
|
||||||
|
} else {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_payment_voucher extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var PaymentVoucherFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Payment Voucher Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (PaymentVoucherID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new PaymentVoucherFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'PV_' . str_replace('/', '-', $header['PaymentVoucherNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pv.*,
|
||||||
|
cs.coaAccountNo,
|
||||||
|
cs.coaDescription,
|
||||||
|
ct.coaAccountNo AS coaTempAccountNo,
|
||||||
|
ct.coaDescription AS coaTempDescription,
|
||||||
|
b.M_BranchName,
|
||||||
|
IFNULL(uCr.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(uPd.M_UserUsername, '') AS PaidByName,
|
||||||
|
IFNULL(uRc.M_UserUsername, '') AS PaidReceiveByName
|
||||||
|
FROM payment_voucher pv
|
||||||
|
LEFT JOIN coa cs ON cs.coaID = pv.PaymentVoucherCoaSourceID
|
||||||
|
LEFT JOIN coa ct ON ct.coaID = pv.PaymentVoucherCoaTemporaryID
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = pv.PaymentVoucherM_BranchCode
|
||||||
|
LEFT JOIN m_user uCr ON uCr.M_UserID = pv.PaymentVoucherUserID
|
||||||
|
LEFT JOIN m_user uPd ON uPd.M_UserID = pv.PaymentVoucherPaidUserID
|
||||||
|
LEFT JOIN m_user uRc ON uRc.M_UserID = pv.PaymentVoucherPaidReceiveUserID
|
||||||
|
WHERE pv.PaymentVoucherIsActive = 'Y'
|
||||||
|
AND pv.PaymentVoucherID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Payment Voucher tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pvd.*,
|
||||||
|
prd.PurchaseRequestDirectNumber,
|
||||||
|
prdd.PurchaseRequestDirectDescription AS ItemDescription,
|
||||||
|
prdd.PurchaseRequestDirectDetailAccount AS ExpenseAccount,
|
||||||
|
prdd.PurchaseRequestDirectDetailTotalRealitationPrice,
|
||||||
|
prdd.PurchaseRequestDirectDetailTotalEstimationPrice,
|
||||||
|
pdc.PurchaseDirectCategoryName,
|
||||||
|
c.coaDescription AS ExpenseAccountName
|
||||||
|
FROM payment_voucher_detail pvd
|
||||||
|
JOIN purchase_request_direct prd ON prd.PurchaseRequestDirectID = pvd.PaymentVoucherDetailPurchaseRequestDirectID
|
||||||
|
JOIN purchase_request_direct_detail prdd ON prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = prd.PurchaseRequestDirectID
|
||||||
|
AND prdd.PurchaseRequestDirectDetailIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_direct_category pdc ON pdc.PurchaseDirectCategoryID = prdd.PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID
|
||||||
|
LEFT JOIN coa c ON c.coaAccountNo = prdd.PurchaseRequestDirectDetailAccount AND c.coaIsActive = 'Y'
|
||||||
|
WHERE pvd.PaymentVoucherDetailIsActive = 'Y'
|
||||||
|
AND pvd.PaymentVoucherDetailPaymentVoucherID = ?
|
||||||
|
ORDER BY pvd.PaymentVoucherDetailID ASC, prdd.PurchaseRequestDirectDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PAYMENT VOUCHER (BUKTI PENGELUARAN KAS / BANK)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$coaSource = '-';
|
||||||
|
if (!empty($header['coaAccountNo'])) {
|
||||||
|
$coaSource = $header['coaAccountNo'] . ' - ' . $header['coaDescription'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$coaTemp = '';
|
||||||
|
if (!empty($header['coaTempAccountNo'])) {
|
||||||
|
$coaTemp = $header['coaTempAccountNo'] . ' - ' . $header['coaTempDescription'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['PaymentVoucherNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['PaymentVoucherDate']), false),
|
||||||
|
array('Sumber Dana', $coaSource, false),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($coaTemp !== '') {
|
||||||
|
$leftItems[] = array('Akun Transit', $coaTemp, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($item[0] === 'Sumber Dana' || $item[0] === 'Akun Transit') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Paid Note langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['PaymentVoucherPaidNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Catatan Bayar', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['PaymentVoucherPaidNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang', $header['M_BranchName'] ?: '-'),
|
||||||
|
array('Tgl Pembayaran', $this->_fmt_date($header['PaymentVoucherPaidDate'])),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 45 + 30 + 72 + 25 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('No. Request Direct', 45, 'L'),
|
||||||
|
array('Kategori', 30, 'L'),
|
||||||
|
array('Deskripsi', 72, 'L'),
|
||||||
|
array('Nominal Bayar', 25, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Set lebar dan alignment kolom untuk metode Row()
|
||||||
|
$pdf->SetWidths(array_column($cols, 1));
|
||||||
|
$pdf->SetAligns(array_column($cols, 2));
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$totalPay = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$amount = floatval($d['PurchaseRequestDirectDetailTotalRealitationPrice']);
|
||||||
|
if ($amount <= 0) {
|
||||||
|
$amount = floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$row_data = array(
|
||||||
|
$no,
|
||||||
|
$d['PurchaseRequestDirectNumber'] ?: '-',
|
||||||
|
$d['PurchaseDirectCategoryName'] ?: '-',
|
||||||
|
$d['ItemDescription'] ?: '-',
|
||||||
|
$this->_fmt_rp($amount),
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->Row($row_data);
|
||||||
|
|
||||||
|
$totalPay += $amount;
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 4), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL PEMBAYARAN', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[4][1], 7, $this->_fmt_rp($totalPay), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln(6);
|
||||||
|
|
||||||
|
// Ringkasan Biaya di Kanan Bawah (sejajar dengan Nominal Bayar)
|
||||||
|
$pdf->Ln(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Voucher ini adalah tanda bukti pengeluaran kas/bank yang sah untuk pembayaran dokumen PR Direct di atas.',
|
||||||
|
'Penerima dana bertanggung jawab penuh atas keabsahan penggunaan dana yang diserahterimakan.',
|
||||||
|
'Realisasi pembayaran harus dilaporkan kembali ke bagian keuangan selambat-lambatnya 3 hari kerja.',
|
||||||
|
'Dokumen ini dicetak secara digital dan divalidasi oleh otorisasi sistem akuntansi ERP.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
531
application/controllers/report/Rpt_pemakaian_item_divisi.php
Normal file
531
application/controllers/report/Rpt_pemakaian_item_divisi.php
Normal file
@@ -0,0 +1,531 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class PemakaianItemDivisiFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
||||||
|
|
||||||
|
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_pemakaian_item_divisi extends MY_Controller
|
||||||
|
{
|
||||||
|
// -- Properti bersama antar fungsi PDF -------------------------------------
|
||||||
|
/** @var PemakaianItemDivisiFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_start_date;
|
||||||
|
private $_end_date;
|
||||||
|
private $_division_id;
|
||||||
|
private $_division_name;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Pemakaian Item per Divisi Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: start_date, end_date, division_id (opsional), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$start_date = trim($this->input->get_post('start_date') ?? '');
|
||||||
|
$end_date = trim($this->input->get_post('end_date') ?? '');
|
||||||
|
$division_id = intval($this->input->get_post('division_id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($start_date === '' || $end_date === '') {
|
||||||
|
$this->sys_error("Periode tanggal harus diisi");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Ambil data dari DB --------------------------------------------
|
||||||
|
$data = $this->_get_data($start_date, $end_date, $division_id);
|
||||||
|
if (empty($data)) {
|
||||||
|
$this->sys_error("Tidak ada data pemakaian item pada periode tersebut");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_start_date = $start_date;
|
||||||
|
$this->_end_date = $end_date;
|
||||||
|
$this->_division_id = $division_id;
|
||||||
|
|
||||||
|
// Ambil nama divisi jika dipilih
|
||||||
|
if ($division_id > 0) {
|
||||||
|
$div = $this->_get_division($division_id);
|
||||||
|
$this->_division_name = $div ? $div['DivisionName'] : '';
|
||||||
|
} else {
|
||||||
|
$this->_division_name = 'Semua Divisi';
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Inisialisasi FPDF custom --------------------------------------
|
||||||
|
$this->_pdf = new PemakaianItemDivisiFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// -- Susun isi halaman ---------------------------------------------
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($data);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// -- Output --------------------------------------------------------
|
||||||
|
$filename = 'PID_' . date('Ymd') . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data divisi
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_division($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT DivisionID, DivisionCode, DivisionName
|
||||||
|
FROM division
|
||||||
|
WHERE DivisionID = ?
|
||||||
|
AND DivisionIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry && $qry->num_rows() > 0 ? $qry->row_array() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data pemakaian item per divisi
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_data($start_date, $end_date, $division_id = 0)
|
||||||
|
{
|
||||||
|
$sql_where = "
|
||||||
|
WHERE iu.ItemUsedIsActive = 'Y'
|
||||||
|
AND iu.ItemUsedIsConfirm = 'Y'
|
||||||
|
AND iu.ItemUsedDate BETWEEN ? AND ?
|
||||||
|
";
|
||||||
|
$params = array($start_date, $end_date);
|
||||||
|
|
||||||
|
if ($division_id > 0) {
|
||||||
|
// Filter by division melalui item_usage
|
||||||
|
$sql_where .= " AND iu.ItemUsedItemUsageID IN (
|
||||||
|
SELECT ItemUsageID FROM item_usage
|
||||||
|
WHERE ItemUsageDivisionID = ?
|
||||||
|
AND ItemUsageIsActive = 'Y'
|
||||||
|
)";
|
||||||
|
$params[] = $division_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
d.DivisionID,
|
||||||
|
d.DivisionCode,
|
||||||
|
d.DivisionName,
|
||||||
|
iu.ItemUsedID,
|
||||||
|
iu.ItemUsedDate,
|
||||||
|
iu.ItemUsedNumber,
|
||||||
|
iu.ItemUsedBatchNo,
|
||||||
|
iu.ItemUsedQty,
|
||||||
|
iu.ItemUsedPrice,
|
||||||
|
iu.ItemUsedTotal,
|
||||||
|
item.M_ItemID,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iunit.ItemUnitName,
|
||||||
|
iunit.ItemUnitCode,
|
||||||
|
us.ItemUsageID,
|
||||||
|
us.ItemUsageDivisionID
|
||||||
|
FROM item_used iu
|
||||||
|
JOIN item_usage us ON us.ItemUsageID = iu.ItemUsedItemUsageID
|
||||||
|
AND us.ItemUsageIsActive = 'Y'
|
||||||
|
JOIN division d ON d.DivisionID = us.ItemUsageDivisionID
|
||||||
|
AND d.DivisionIsActive = 'Y'
|
||||||
|
JOIN m_item item ON item.M_ItemID = iu.ItemUsedM_ItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
JOIN itemunit iunit ON iunit.ItemUnitID = iu.ItemUsedItemUnitID
|
||||||
|
AND iunit.ItemUnitIsActive = 'Y'
|
||||||
|
$sql_where
|
||||||
|
ORDER BY d.DivisionCode ASC, d.DivisionName ASC, iu.ItemUsedDate ASC, iu.ItemUsedNumber ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, $params);
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Laporan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
// -- Judul utama -------------------------------------------------------
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'LAPORAN PEMAKAIAN ITEM PER DIVISI', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 30;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// -- Kolom Kiri --------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Periode Awal', $this->_fmt_date($this->_start_date), false),
|
||||||
|
array('Periode Akhir', $this->_fmt_date($this->_end_date), false),
|
||||||
|
array('Divisi', $this->_division_name, true),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// -- Kolom Kanan -------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Print Oleh', $this->_username),
|
||||||
|
array('Tgl Print', $this->_pdf->printDate),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel pemakaian item per divisi
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($data)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
// -- Definisi kolom: [label, lebar, align] -----------------------------
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 8 + 68 + 15 + 15 + 22 + 22 + 22 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 6, 'C'),
|
||||||
|
array('Tgl', 16, 'C'),
|
||||||
|
array('Nama Item', 62, 'L'),
|
||||||
|
array('Batch No', 24, 'C'),
|
||||||
|
array('Unit', 14, 'C'),
|
||||||
|
array('Qty', 10, 'R'),
|
||||||
|
array('Harga', 18, 'R'),
|
||||||
|
array('Total', 30, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$no = 1;
|
||||||
|
$prevDivID = null;
|
||||||
|
$divTotalQty = 0;
|
||||||
|
$divTotalVal = 0;
|
||||||
|
$grandTotalQty = 0;
|
||||||
|
$grandTotalVal = 0;
|
||||||
|
|
||||||
|
// Simpan posisi awal Y untuk setiap divisi — dipakai untuk bounding box
|
||||||
|
$divStartY = 0;
|
||||||
|
|
||||||
|
foreach ($data as $d) {
|
||||||
|
$divID = $d['DivisionID'];
|
||||||
|
|
||||||
|
// -- Jika berganti divisi, cetak subtotal divisi sebelumnya ----------
|
||||||
|
if ($prevDivID !== null && $divID !== $prevDivID) {
|
||||||
|
$this->_pdf_divisi_subtotal($divTotalQty, $divTotalVal);
|
||||||
|
$grandTotalQty += $divTotalQty;
|
||||||
|
$grandTotalVal += $divTotalVal;
|
||||||
|
$divTotalQty = 0;
|
||||||
|
$divTotalVal = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Jika divisi baru, cetak header nama divisi ---------------------
|
||||||
|
if ($prevDivID === null || $divID !== $prevDivID) {
|
||||||
|
// Cek sisa ruang: butuh minimal 8+7+6*n+8 ˜ 40mm untuk header+1 baris+subtotal
|
||||||
|
if ($pdf->GetY() > 230) {
|
||||||
|
$pdf->AddPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$divStartY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Nama Divisi
|
||||||
|
$pdf->SetFillColor(50, 80, 130);
|
||||||
|
$pdf->SetTextColor(255, 255, 255);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
||||||
|
$pdf->Cell($pageW, 7, ' ' . $d['DivisionName'] . ' (' . $d['DivisionCode'] . ')', 1, 1, 'L', true);
|
||||||
|
$pdf->SetTextColor(0, 0, 0);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 6, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$no = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Cek apakah perlu halaman baru (min 12mm untuk 1 baris + subtotal) -
|
||||||
|
if ($pdf->GetY() > 258) {
|
||||||
|
$pdf->AddPage();
|
||||||
|
// Ulang header kolom di halaman baru
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 6, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Baris data item -----------------------------------------------
|
||||||
|
$pdf->SetLineWidth(0.2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 7.5);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
|
||||||
|
$itemDesc = $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-');
|
||||||
|
$batchNo = $d['ItemUsedBatchNo'] ?: '-';
|
||||||
|
$qty = floatval($d['ItemUsedQty']);
|
||||||
|
$price = floatval($d['ItemUsedPrice']);
|
||||||
|
$total = floatval($d['ItemUsedTotal']);
|
||||||
|
|
||||||
|
// Simpan posisi Y sebelum cell untuk wrap detection
|
||||||
|
$beforeY = $pdf->GetY();
|
||||||
|
|
||||||
|
$pdf->Cell($cols[0][1], 5, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 5, $this->_fmt_date($d['ItemUsedDate']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[2][1], 5, $itemDesc, 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[3][1], 5, $batchNo, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 5, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[5][1], 5, $this->_fmt_qty($qty), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[6][1], 5, $this->_fmt_rp($price), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[7][1], 5, $this->_fmt_rp($total), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$divTotalQty += $qty;
|
||||||
|
$divTotalVal += $total;
|
||||||
|
$prevDivID = $divID;
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Subtotal divisi terakhir -----------------------------------------
|
||||||
|
if ($prevDivID !== null) {
|
||||||
|
$this->_pdf_divisi_subtotal($divTotalQty, $divTotalVal);
|
||||||
|
$grandTotalQty += $divTotalQty;
|
||||||
|
$grandTotalVal += $divTotalVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Grand Total ------------------------------------------------------
|
||||||
|
$pdf->Ln(3);
|
||||||
|
|
||||||
|
// Cek ruang untuk grand total
|
||||||
|
if ($pdf->GetY() > 270) {
|
||||||
|
$pdf->AddPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->SetLineWidth(0.4);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
||||||
|
$pdf->SetFillColor(180, 200, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
|
||||||
|
$spanSum = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->Cell($spanSum, 7, 'GRAND TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_qty($grandTotalQty), 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[6][1], 7, '', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[7][1], 7, $this->_fmt_rp($grandTotalVal), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
|
||||||
|
// -- Ringkasan Akhir --------------------------------------------------
|
||||||
|
$summaryX = 15 + $pageW - 90;
|
||||||
|
$cW1 = 50;
|
||||||
|
$cW2 = 40;
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->SetX($summaryX);
|
||||||
|
$pdf->Cell($cW1, 5, 'Total Item Digunakan', 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($cW2, 5, $this->_fmt_qty($grandTotalQty) . ' ' . 'pcs', 0, 1, 'R');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->SetX($summaryX);
|
||||||
|
$pdf->Cell($cW1, 5, 'Total Nilai Pemakaian', 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($cW2, 5, $this->_fmt_rp($grandTotalVal), 0, 1, 'R');
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SUB-SECTION: Subtotal per Divisi
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_divisi_subtotal($qty, $val)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
// Gunakan lebar kolom yang sama persis dengan _pdf_data()
|
||||||
|
$cols = array(
|
||||||
|
array('No', 6, 'C'),
|
||||||
|
array('Tgl', 16, 'C'),
|
||||||
|
array('Nama Item', 62, 'L'),
|
||||||
|
array('Batch No', 24, 'C'),
|
||||||
|
array('Unit', 14, 'C'),
|
||||||
|
array('Qty', 10, 'R'),
|
||||||
|
array('Harga', 18, 'R'),
|
||||||
|
array('Total', 30, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($pdf->GetY() > 270) {
|
||||||
|
$pdf->AddPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$spanSum = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(235, 240, 248);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->Cell($spanSum, 6, 'Sub Total', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_qty($qty), 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[6][1], 6, '', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[7][1], 6, $this->_fmt_rp($val), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
$pdf->Ln(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Laporan ini menampilkan seluruh pemakaian item yang telah dikonfirmasi pada periode yang dipilih.',
|
||||||
|
'Data pemakaian dikelompokkan berdasarkan divisi yang melakukan pemakaian.',
|
||||||
|
'Harga yang ditampilkan adalah harga rata-rata pada saat pemakaian item.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan monitoring pemakaian item.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
427
application/controllers/report/Rpt_penerimaan_mutasi.php
Normal file
427
application/controllers/report/Rpt_penerimaan_mutasi.php
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class MutasiPenerimaanFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_penerimaan_mutasi extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var MutasiPenerimaanFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Mutasi Penerimaan (Receive Mutasi) Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (MutasiHandoverID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
|
||||||
|
// Validasi: hanya dokumen berstatus Received yang bisa dicetak
|
||||||
|
if ($header['MutasiHandoverStatus'] !== 'Received') {
|
||||||
|
$this->sys_error("Dokumen belum diterima (Status: " . $header['MutasiHandoverStatus'] . ")");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new MutasiPenerimaanFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'PM_' . str_replace('/', '-', $header['MutasiHandoverNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
mh.*,
|
||||||
|
mr.MutasiRequestNumber,
|
||||||
|
ic.itemCategoryID,
|
||||||
|
ic.itemCategoryName,
|
||||||
|
a.M_BranchID AS branch_asal_id,
|
||||||
|
a.M_BranchCode AS branch_asal_code,
|
||||||
|
a.M_BranchName AS branch_asal_name,
|
||||||
|
b.M_BranchID AS branch_tujuan_id,
|
||||||
|
b.M_BranchCode AS branch_tujuan_code,
|
||||||
|
b.M_BranchName AS branch_tujuan_name,
|
||||||
|
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(ur.M_UserUsername, '') AS ReceiveByName,
|
||||||
|
CASE
|
||||||
|
WHEN wh.WarehouseType = 'B' THEN CONCAT(wh.WarehouseCode, ' ', wh.WarehouseName, ' - ', b.M_BranchName)
|
||||||
|
ELSE wh.WarehouseName
|
||||||
|
END AS WarehouseName,
|
||||||
|
r.M_RuanganName
|
||||||
|
FROM mutasi_handover mh
|
||||||
|
LEFT JOIN mutasi_request mr ON mr.MutasiRequestID = mh.MutasiHandoverMutasiRequestID
|
||||||
|
JOIN item_category ic ON ic.itemCategoryID = mh.MutasiHandoverItemCategoryID
|
||||||
|
AND ic.itemCategoryIsActive = 'Y'
|
||||||
|
JOIN m_branch a ON a.M_BranchID = mh.MutasiHandoverFromBranchID
|
||||||
|
AND a.M_BranchIsActive = 'Y'
|
||||||
|
JOIN m_branch b ON b.M_BranchID = mh.MutasiHandoverToBranchID
|
||||||
|
AND b.M_BranchIsActive = 'Y'
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = mh.MutasiHandoverUserID
|
||||||
|
LEFT JOIN m_user ur ON ur.M_UserID = mh.MutasiHandoverReceiveUserID
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = mh.MutasiHandoverReceiveWarehouseID
|
||||||
|
AND wh.WarehouseIsActive = 'Y'
|
||||||
|
LEFT JOIN m_ruangan r ON r.M_RuanganID = mh.MutasiHandoverReceiveM_RuanganID
|
||||||
|
AND r.M_RuanganIsActive = 'Y'
|
||||||
|
WHERE mh.MutasiHandoverID = ?
|
||||||
|
AND mh.MutasiHandoverIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Penerimaan Mutasi tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
mhd.*,
|
||||||
|
i.M_ItemCode,
|
||||||
|
i.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
st.StockStockNumber AS StockToNumber,
|
||||||
|
sf.StockStockNumber AS StockFromNumber
|
||||||
|
FROM mutasi_handover_detail mhd
|
||||||
|
LEFT JOIN m_item i ON i.M_ItemID = mhd.MutasiHandoverDetailM_ItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = mhd.MutasiHandoverDetailItemUnitID
|
||||||
|
LEFT JOIN stock sf ON sf.StockID = mhd.MutasiHandoverDetailStockID_From
|
||||||
|
LEFT JOIN stock st ON st.StockID = mhd.MutasiHandoverDetailStockID_To
|
||||||
|
WHERE mhd.MutasiHandoverDetailMutasiHandoverID = ?
|
||||||
|
AND mhd.MutasiHandoverDetailIsActive = 'Y'
|
||||||
|
ORDER BY mhd.MutasiHandoverDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PENERIMAAN MUTASI', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 30;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor Handover', $header['MutasiHandoverNumber'], true),
|
||||||
|
array('No. Request', $header['MutasiRequestNumber'] ?: '-', false),
|
||||||
|
array('Tgl Kirim', $this->_fmt_date($header['MutasiHandoverDate']), false),
|
||||||
|
array('Tgl Terima', $this->_fmt_date($header['MutasiHandoverReceiveDate']), false),
|
||||||
|
array('Status', $header['MutasiHandoverStatus'], false),
|
||||||
|
array('Kategori', $header['itemCategoryName'], false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan (Note) langsung di bawah Kategori
|
||||||
|
if (!empty($header['MutasiHandoverNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['MutasiHandoverNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang Asal', $header['branch_asal_name']),
|
||||||
|
array('Cabang Tujuan', $header['branch_tujuan_name']),
|
||||||
|
array('Warehouse Tujuan', $header['WarehouseName'] ?: '-'),
|
||||||
|
array('Ruangan Tujuan', $header['M_RuanganName'] ?: '-'),
|
||||||
|
array('Diterima Oleh', $header['MutasiHandoverStatus'] === 'Received' ? $header['ReceiveByName'] : '-'),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName']),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 72 + 15 + 15 + 22 + 22 + 26 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama Item', 72, 'L'),
|
||||||
|
array('Unit', 15, 'C'),
|
||||||
|
array('Qty', 15, 'R'),
|
||||||
|
array('Nilai Buku', 22, 'R'),
|
||||||
|
array('Total', 22, 'R'),
|
||||||
|
array('Stock Tujuan', 26, 'C'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 7);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 7.5);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_val = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$bookValue = floatval($d['MutasiHandoverDetailBookValue'] ?? 0);
|
||||||
|
$qty = floatval($d['MutasiHandoverDetailQty'] ?? 0);
|
||||||
|
$lineTotal = $qty * $bookValue;
|
||||||
|
$stockTo = $d['StockToNumber'] ?: '-';
|
||||||
|
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($bookValue), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($lineTotal), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[6][1], 6, $stockTo, 1, 0, 'C');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_val += $lineTotal;
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 6), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[6][1], 7, '', 1, 0, 'C', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// ── Ringkasan nilai (rata kanan) ──────────────────────────────────────
|
||||||
|
$pdf->Ln(3);
|
||||||
|
$summary = array(
|
||||||
|
array('Total Nilai Penerimaan', $this->_fmt_rp($header['MutasiHandoverTotalValue'])),
|
||||||
|
);
|
||||||
|
|
||||||
|
$cW1 = 50;
|
||||||
|
$cW2 = 40;
|
||||||
|
$offsetX = 15 + $this->_pageW - $cW1 - $cW2;
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Penerimaan mutasi ini dilakukan berdasarkan dokumen handover (penyerahan) yang telah dikirim oleh cabang asal.',
|
||||||
|
'Penerima wajib memeriksa kesesuaian jumlah, jenis, dan kondisi barang dengan dokumen handover.',
|
||||||
|
'Setelah diterima, barang menjadi tanggung jawab cabang tujuan dan akan dicatat dalam stok tujuan.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses mutasi barang.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
403
application/controllers/report/Rpt_pengeluaran_barang.php
Normal file
403
application/controllers/report/Rpt_pengeluaran_barang.php
Normal file
@@ -0,0 +1,403 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class PengeluaranBarangFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
||||||
|
|
||||||
|
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_pengeluaran_barang extends MY_Controller
|
||||||
|
{
|
||||||
|
// -- Properti bersama antar fungsi PDF -------------------------------------
|
||||||
|
/** @var PengeluaranBarangFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Pengeluaran Barang Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (T_ItemOutID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Ambil data header & detail dari DB ----------------------------
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// -- Inisialisasi FPDF custom --------------------------------------
|
||||||
|
$this->_pdf = new PengeluaranBarangFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// -- Susun isi halaman ---------------------------------------------
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// -- Output --------------------------------------------------------
|
||||||
|
$filename = 'IO_' . str_replace('/', '-', $header['T_ItemOutNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
io.*,
|
||||||
|
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(ur.M_UserUsername, '') AS ReceiveByName,
|
||||||
|
IFNULL(ua.M_UserUsername, '') AS ApprovedByName,
|
||||||
|
wh.WarehouseCode,
|
||||||
|
wh.WarehouseName,
|
||||||
|
wh.WarehouseType,
|
||||||
|
d.DivisionCode,
|
||||||
|
d.DivisionName
|
||||||
|
FROM t_item_out io
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = io.T_ItemOutUserID
|
||||||
|
LEFT JOIN m_user ur ON ur.M_UserID = io.T_ItemOutReceiveUserID
|
||||||
|
LEFT JOIN m_user ua ON ua.M_UserID = io.T_ItemOutApproveID
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = io.T_ItemOutWarehouseID
|
||||||
|
AND wh.WarehouseIsActive = 'Y'
|
||||||
|
LEFT JOIN division d ON d.DivisionID = io.T_ItemOutDivisionID
|
||||||
|
AND d.DivisionIsActive = 'Y'
|
||||||
|
WHERE io.T_ItemOutID = ?
|
||||||
|
AND io.T_ItemOutIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Pengeluaran Barang tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
iod.*,
|
||||||
|
i.M_ItemCode,
|
||||||
|
i.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
rod.RequestItemOutDetailQty AS RequestQty,
|
||||||
|
rod.RequestItemOutDetailStatus AS RequestStatus
|
||||||
|
FROM t_item_out_detail iod
|
||||||
|
LEFT JOIN m_item i ON i.M_ItemID = iod.T_ItemOutDetailM_ItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = iod.T_ItemOutDetailItemUnitID
|
||||||
|
LEFT JOIN request_item_out_detail rod
|
||||||
|
ON rod.RequestItemOutDetailID = iod.T_ItemOutDetailRequestItemOutDetailID
|
||||||
|
AND rod.RequestItemOutDetailIsActive = 'Y'
|
||||||
|
WHERE iod.T_ItemOutDetailT_ItemOutID = ?
|
||||||
|
AND iod.T_ItemOutDetailIsActive = 'Y'
|
||||||
|
ORDER BY iod.T_ItemOutDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// -- Judul utama -------------------------------------------------------
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PENGELUARAN BARANG (ITEM OUT)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 30;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// -- Kolom Kiri --------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor IO', $header['T_ItemOutNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['T_ItemOutDate']), false),
|
||||||
|
array('Status', $header['T_ItemOutStatus'], false),
|
||||||
|
array('Confirm', $header['T_ItemOutIsConfirm'] === 'Y' ? 'Ya' : 'Tidak', false),
|
||||||
|
array('Divisi', $header['DivisionName'] ?: '-', false),
|
||||||
|
array('Gudang', $header['WarehouseName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan (Note) langsung di bawah field terakhir
|
||||||
|
if (!empty($header['T_ItemOutNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['T_ItemOutNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// -- Kolom Kanan -------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName'] ?: '-'),
|
||||||
|
array('Dibuat Tgl', $this->_fmt_datetime($header['T_ItemOutCreated'])),
|
||||||
|
array('Penerima', $header['ReceiveByName'] ?: '-'),
|
||||||
|
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
||||||
|
array('Tgl Approve', $header['T_ItemOutApproveDate'] ? $this->_fmt_datetime($header['T_ItemOutApproveDate']) : '-'),
|
||||||
|
array('Tgl Dikonfirmasi', $header['T_ItemOutIsConfirmDate'] ? $this->_fmt_datetime($header['T_ItemOutIsConfirmDate']) : '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
// -- Definisi kolom: [label, lebar, align] -----------------------------
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 72 + 20 + 20 + 30 + 30 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama Item', 72, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 20, 'R'),
|
||||||
|
array('Batch No.', 30, 'C'),
|
||||||
|
array('Qty Request', 30, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_qty = 0;
|
||||||
|
$total_req = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$qty = floatval($d['T_ItemOutDetailQty'] ?? 0);
|
||||||
|
$qtyReq = floatval($d['T_ItemOutDetailRequestItemOutDetailID'] > 0 ? $qty : 0);
|
||||||
|
$batchNo = $d['T_ItemOutDetailItemBatchNo'] ?? '';
|
||||||
|
// Jika batch no berupa JSON array, decode untuk ditampilkan
|
||||||
|
$batchDisplay = $batchNo;
|
||||||
|
if (strpos($batchNo, '[') === 0) {
|
||||||
|
$decoded = json_decode($batchNo, true);
|
||||||
|
if (is_array($decoded) && count($decoded) > 0) {
|
||||||
|
$parts = array();
|
||||||
|
foreach ($decoded as $b) {
|
||||||
|
$parts[] = isset($b['batchNo']) ? $b['batchNo'] : (isset($b['BatchNo']) ? $b['BatchNo'] : (is_string($b) ? $b : '-'));
|
||||||
|
}
|
||||||
|
$batchDisplay = implode(', ', $parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $batchDisplay, 1, 0, 'C');
|
||||||
|
$reqQty = isset($d['RequestQty']) ? floatval($d['RequestQty']) : 0;
|
||||||
|
$pdf->Cell($cols[5][1], 6, $reqQty > 0 ? $this->_fmt_qty($reqQty) : '-', 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_qty += $qty;
|
||||||
|
if ($reqQty > 0) {
|
||||||
|
$total_req += $reqQty;
|
||||||
|
}
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 4), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[4][1], 7, '', 1, 0, 'C', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_qty($total_qty), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Barang yang dikeluarkan harus sesuai dengan jumlah dan spesifikasi yang tercantum dalam dokumen ini.',
|
||||||
|
'Penerima barang wajib memeriksa dan memverifikasi kesesuaian barang sebelum menerima.',
|
||||||
|
'Dokumen ini merupakan bukti sah pengeluaran barang dari gudang.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan administrasi perusahaan.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
429
application/controllers/report/Rpt_penyerahan_mutasi.php
Normal file
429
application/controllers/report/Rpt_penyerahan_mutasi.php
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class MutasiHandoverFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_penyerahan_mutasi extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var MutasiHandoverFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Mutasi Handover (Penyerahan Mutasi) Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (MutasiHandoverID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new MutasiHandoverFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'PH_' . str_replace('/', '-', $header['MutasiHandoverNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
mh.*,
|
||||||
|
mr.MutasiRequestNumber,
|
||||||
|
ic.itemCategoryID,
|
||||||
|
ic.itemCategoryName,
|
||||||
|
a.M_BranchID AS branch_asal_id,
|
||||||
|
a.M_BranchCode AS branch_asal_code,
|
||||||
|
a.M_BranchName AS branch_asal_name,
|
||||||
|
b.M_BranchID AS branch_tujuan_id,
|
||||||
|
b.M_BranchCode AS branch_tujuan_code,
|
||||||
|
b.M_BranchName AS branch_tujuan_name,
|
||||||
|
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(ur.M_UserUsername, '') AS ReceiveByName,
|
||||||
|
CASE
|
||||||
|
WHEN wh.WarehouseType = 'B' THEN CONCAT(wh.WarehouseCode, ' ', wh.WarehouseName, ' - ', b.M_BranchName)
|
||||||
|
ELSE wh.WarehouseName
|
||||||
|
END AS WarehouseName,
|
||||||
|
r.M_RuanganName
|
||||||
|
FROM mutasi_handover mh
|
||||||
|
LEFT JOIN mutasi_request mr ON mr.MutasiRequestID = mh.MutasiHandoverMutasiRequestID
|
||||||
|
JOIN item_category ic ON ic.itemCategoryID = mh.MutasiHandoverItemCategoryID
|
||||||
|
AND ic.itemCategoryIsActive = 'Y'
|
||||||
|
JOIN m_branch a ON a.M_BranchID = mh.MutasiHandoverFromBranchID
|
||||||
|
AND a.M_BranchIsActive = 'Y'
|
||||||
|
JOIN m_branch b ON b.M_BranchID = mh.MutasiHandoverToBranchID
|
||||||
|
AND b.M_BranchIsActive = 'Y'
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = mh.MutasiHandoverUserID
|
||||||
|
LEFT JOIN m_user ur ON ur.M_UserID = mh.MutasiHandoverReceiveUserID
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = mh.MutasiHandoverReceiveWarehouseID
|
||||||
|
AND wh.WarehouseIsActive = 'Y'
|
||||||
|
LEFT JOIN m_ruangan r ON r.M_RuanganID = mh.MutasiHandoverReceiveM_RuanganID
|
||||||
|
AND r.M_RuanganIsActive = 'Y'
|
||||||
|
WHERE mh.MutasiHandoverID = ?
|
||||||
|
AND mh.MutasiHandoverIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Penyerahan Mutasi tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
mhd.*,
|
||||||
|
i.M_ItemCode,
|
||||||
|
i.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM mutasi_handover_detail mhd
|
||||||
|
LEFT JOIN m_item i ON i.M_ItemID = mhd.MutasiHandoverDetailM_ItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = mhd.MutasiHandoverDetailItemUnitID
|
||||||
|
WHERE mhd.MutasiHandoverDetailMutasiHandoverID = ?
|
||||||
|
AND mhd.MutasiHandoverDetailIsActive = 'Y'
|
||||||
|
ORDER BY mhd.MutasiHandoverDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PENYERAHAN MUTASI (HANDOVER)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 30;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor Handover', $header['MutasiHandoverNumber'], true),
|
||||||
|
array('No. Request', $header['MutasiRequestNumber'] ?: '-', false),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['MutasiHandoverDate']), false),
|
||||||
|
array('Status', $header['MutasiHandoverStatus'], false),
|
||||||
|
array('Kategori', $header['itemCategoryName'], false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan (Note) langsung di bawah Status
|
||||||
|
if (!empty($header['MutasiHandoverNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['MutasiHandoverNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang Asal', $header['branch_asal_name']),
|
||||||
|
array('Cabang Tujuan', $header['branch_tujuan_name']),
|
||||||
|
array('Warehouse Tujuan', $header['WarehouseName'] ?: '-'),
|
||||||
|
array('Ruangan Tujuan', $header['M_RuanganName'] ?: '-'),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName']),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tanggal terima di kolom kanan
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Tgl Terima', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $this->_fmt_date($header['MutasiHandoverReceiveDate']), 0, 1, 'L');
|
||||||
|
|
||||||
|
// Penerima di kolom kanan
|
||||||
|
if ($header['MutasiHandoverStatus'] === 'Received') {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Diterima Oleh', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $header['ReceiveByName'] ?: '-', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 80 + 20 + 20 + 25 + 27 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama Item', 80, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 20, 'R'),
|
||||||
|
array('Nilai Buku', 25, 'R'),
|
||||||
|
array('Total', 27, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_val = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$bookValue = floatval($d['MutasiHandoverDetailBookValue'] ?? 0);
|
||||||
|
$qty = floatval($d['MutasiHandoverDetailQty'] ?? 0);
|
||||||
|
$lineTotal = $qty * $bookValue;
|
||||||
|
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($bookValue), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($lineTotal), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_val += $lineTotal;
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($total_val), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// ── Ringkasan nilai (rata kanan) ──────────────────────────────────────
|
||||||
|
$pdf->Ln(3);
|
||||||
|
$summary = array(
|
||||||
|
array('Total Nilai Penyerahan', $this->_fmt_rp($header['MutasiHandoverTotalValue'])),
|
||||||
|
);
|
||||||
|
|
||||||
|
$cW1 = 50;
|
||||||
|
$cW2 = 40;
|
||||||
|
$offsetX = 15 + $this->_pageW - $cW1 - $cW2;
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Penyerahan mutasi ini dilakukan berdasarkan dokumen mutasi yang telah disetujui sebelumnya.',
|
||||||
|
'Barang yang diserahkan harus sesuai dengan jumlah dan spesifikasi yang tercantum dalam dokumen ini.',
|
||||||
|
'Penerima barang wajib memeriksa dan memverifikasi kesesuaian barang sebelum menerima.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses mutasi barang.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
395
application/controllers/report/Rpt_pr_direct.php
Normal file
395
application/controllers/report/Rpt_pr_direct.php
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal.
|
||||||
|
// =============================================================================
|
||||||
|
class PrdFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_pr_direct extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var PrdFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Purchase Request Direct Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (PurchaseRequestDirectID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new PrdFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'PRD_' . str_replace('/', '-', $header['PurchaseRequestDirectNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
prd.*,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
IFNULL(u.M_UserUsername,'') AS CreatedByName,
|
||||||
|
IFNULL(ua.M_UserUsername,'') AS ApprovedByName
|
||||||
|
FROM purchase_request_direct prd
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = prd.PurchaseRequestDirectM_BranchCode
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = prd.PurchaseRequestDirectS_RegionalID
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = prd.PurchaseRequestCreatedUserID
|
||||||
|
LEFT JOIN m_user ua ON ua.M_UserID = prd.PurchaseRequestDirectApprovedBy
|
||||||
|
WHERE prd.PurchaseRequestDirectID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Purchase Request Direct tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
prdd.*,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
pdc.PurchaseDirectCategoryName
|
||||||
|
FROM purchase_request_direct_detail prdd
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = prdd.PurchaseRequestDirectDetailItemUnitID
|
||||||
|
LEFT JOIN purchase_direct_category pdc ON pdc.PurchaseDirectCategoryID = prdd.PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID
|
||||||
|
WHERE prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = ?
|
||||||
|
AND prdd.PurchaseRequestDirectDetailIsActive = 'Y'
|
||||||
|
ORDER BY prdd.PurchaseRequestDirectDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PURCHASE REQUEST DIRECT (PRD)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$half = $pageW / 2;
|
||||||
|
$lbl = 28;
|
||||||
|
$val = $half - $lbl - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$left = array(
|
||||||
|
array('Nomor', $header['PurchaseRequestDirectNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDirectDate']), false),
|
||||||
|
array('Tanggal Pelaksanaan', $this->_fmt_date($header['PurchaseRequestDirectDateUse']), false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($left as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lbl, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if (isset($item[2]) && $item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($val, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan langsung di bawah info kiri (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['PurchaseRequestDirectDescription'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lbl, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($val, 5, $header['PurchaseRequestDirectDescription'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $half;
|
||||||
|
|
||||||
|
$right = array(
|
||||||
|
array('Cabang', $header['M_BranchName']),
|
||||||
|
array('Regional', $header['S_RegionalName']),
|
||||||
|
array('Alamat', $header['M_BranchAddress']),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName']),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($right as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lbl, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat') {
|
||||||
|
$pdf->MultiCell($val, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($val, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 50 + 30 + 15 + 22 + 28 + 27 = 180 (Qty Disetujui dihapus)
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 50, 'L'),
|
||||||
|
array('Kategori', 30, 'L'),
|
||||||
|
array('Unit', 15, 'C'),
|
||||||
|
array('Qty Request', 22, 'R'),
|
||||||
|
array('Harga', 28, 'R'),
|
||||||
|
array('Total', 27, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_est = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['PurchaseRequestDirectDescription'] ?: $d['ItemUnitName'], 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['PurchaseDirectCategoryName'] ?: '-', 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $d['ItemUnitName'], 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['PurchaseRequestDirectDetailAmountRequest']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailEstimationPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailTotalEstimationPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_est += floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 6), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[6][1], 7, $this->_fmt_rp($total_est), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// ── Ringkasan nilai (rata kanan) ──────────────────────────────────────
|
||||||
|
$pdf->Ln(4);
|
||||||
|
$summary = array(
|
||||||
|
array('Total Estimasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalEstimation'])),
|
||||||
|
array('Adjustment', $this->_fmt_rp($header['PurchaseRequestDirectAdjustment'])),
|
||||||
|
array('Total Realisasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalRealitation'])),
|
||||||
|
array('Total Pembayaran', $this->_fmt_rp($header['PurchaseRequestDirectTotalPaid'])),
|
||||||
|
);
|
||||||
|
|
||||||
|
$cW1 = 50;
|
||||||
|
$cW2 = 40;
|
||||||
|
$offsetX = 15 + $pageW - $cW1 - $cW2;
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Pengajuan pembelian ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses pembelian dilakukan.',
|
||||||
|
'Barang/jasa yang dibeli harus sesuai dengan spesifikasi dan kebutuhan yang tercantum dalam dokumen ini.',
|
||||||
|
'Pembayaran dilakukan setelah barang/jasa diterima dan diverifikasi sesuai pesanan.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses pengadaan.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
412
application/controllers/report/Rpt_pr_direct_approval.php
Normal file
412
application/controllers/report/Rpt_pr_direct_approval.php
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal.
|
||||||
|
// =============================================================================
|
||||||
|
class PrdApprovalFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_pr_direct_approval extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var PrdApprovalFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Purchase Request Direct Approval Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (PurchaseRequestDirectID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
|
||||||
|
// Validasi: hanya status Approved, Paid, atau Completed yang bisa dicetak di report Approval
|
||||||
|
if (!in_array($header['PurchaseRequestDirectStatus'], array('Approved', 'Paid', 'Completed'))) {
|
||||||
|
$this->sys_error("Dokumen belum disetujui (Status: " . $header['PurchaseRequestDirectStatus'] . ")");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new PrdApprovalFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'PRD_APPROVAL_' . str_replace('/', '-', $header['PurchaseRequestDirectNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
prd.*,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
IFNULL(u.M_UserUsername,'') AS CreatedByName,
|
||||||
|
IFNULL(ua.M_UserUsername,'') AS ApprovedByName
|
||||||
|
FROM purchase_request_direct prd
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = prd.PurchaseRequestDirectM_BranchCode
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = prd.PurchaseRequestDirectS_RegionalID
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = prd.PurchaseRequestCreatedUserID
|
||||||
|
LEFT JOIN m_user ua ON ua.M_UserID = prd.PurchaseRequestDirectApprovedBy
|
||||||
|
WHERE prd.PurchaseRequestDirectID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Purchase Request Direct tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
prdd.*,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
pdc.PurchaseDirectCategoryName
|
||||||
|
FROM purchase_request_direct_detail prdd
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = prdd.PurchaseRequestDirectDetailItemUnitID
|
||||||
|
LEFT JOIN purchase_direct_category pdc ON pdc.PurchaseDirectCategoryID = prdd.PurchaseRequestDirectDetailPurchaseRequestDirectCategoryID
|
||||||
|
WHERE prdd.PurchaseRequestDirectDetailPurchaseRequestDirectID = ?
|
||||||
|
AND prdd.PurchaseRequestDirectDetailIsActive = 'Y'
|
||||||
|
ORDER BY prdd.PurchaseRequestDirectDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PURCHASE REQUEST DIRECT APPROVAL (PRD)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
// ── Info dokumen: 2 kolom (kiri & kanan) ─────────────────────────────
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['PurchaseRequestDirectNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDirectDate']), false),
|
||||||
|
array('Tanggal Pelaksanaan', $this->_fmt_date($header['PurchaseRequestDirectDateUse']), false),
|
||||||
|
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestDirectApprovedDate'])),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if (isset($item[2]) && $item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan & Catatan langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['PurchaseRequestDirectDescription'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['PurchaseRequestDirectDescription'], 0, 'L');
|
||||||
|
}
|
||||||
|
if (!empty($header['PurchaseRequestDirectNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Catatan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['PurchaseRequestDirectNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang', $header['M_BranchName']),
|
||||||
|
array('Regional', $header['S_RegionalName']),
|
||||||
|
array('Alamat', $header['M_BranchAddress']),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName']),
|
||||||
|
array('Disetujui Oleh', $header['ApprovedByName']),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 42 + 25 + 15 + 17 + 18 + 28 + 27 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 42, 'L'),
|
||||||
|
array('Kategori', 25, 'L'),
|
||||||
|
array('Unit', 15, 'C'),
|
||||||
|
array('Qty Request', 17, 'R'),
|
||||||
|
array('Qty Disetujui', 18, 'R'),
|
||||||
|
array('Harga', 28, 'R'),
|
||||||
|
array('Total', 27, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_est = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['PurchaseRequestDirectDescription'] ?: $d['ItemUnitName'], 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['PurchaseDirectCategoryName'] ?: '-', 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $d['ItemUnitName'], 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['PurchaseRequestDirectDetailAmountRequest']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_qty($d['PurchaseRequestDirectDetailAmount']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailEstimationPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[7][1], 6, $this->_fmt_rp($d['PurchaseRequestDirectDetailTotalEstimationPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_est += floatval($d['PurchaseRequestDirectDetailTotalEstimationPrice']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 7), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[7][1], 7, $this->_fmt_rp($total_est), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// ── Ringkasan nilai (rata kanan) ──────────────────────────────────────
|
||||||
|
$pdf->Ln(4);
|
||||||
|
$summary = array(
|
||||||
|
array('Total Estimasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalEstimation'])),
|
||||||
|
array('Adjustment', $this->_fmt_rp($header['PurchaseRequestDirectAdjustment'])),
|
||||||
|
array('Total Realisasi', $this->_fmt_rp($header['PurchaseRequestDirectTotalRealitation'])),
|
||||||
|
array('Total Pembayaran', $this->_fmt_rp($header['PurchaseRequestDirectTotalPaid'])),
|
||||||
|
);
|
||||||
|
|
||||||
|
$cW1 = 50;
|
||||||
|
$cW2 = 40;
|
||||||
|
$offsetX = 15 + $pageW - $cW1 - $cW2;
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Pengajuan pembelian ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses pembelian dilakukan.',
|
||||||
|
'Barang/jasa yang dibeli harus sesuai dengan spesifikasi dan kebutuhan yang tercantum dalam dokumen ini.',
|
||||||
|
'Pembayaran dilakukan setelah barang/jasa diterima dan diverifikasi sesuai pesanan.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses pengadaan.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
463
application/controllers/report/Rpt_purchase_order_asset.php
Normal file
463
application/controllers/report/Rpt_purchase_order_asset.php
Normal file
@@ -0,0 +1,463 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class PurchaseOrderAssetFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_purchase_order_asset extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var PurchaseOrderAssetFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Purchase Order Asset Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (PurchaseOrderID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new PurchaseOrderAssetFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'PO_ASSET_' . str_replace('/', '-', $header['PurchaseOrderNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
po.*,
|
||||||
|
sup.SupplierName,
|
||||||
|
sup.SupplierAddress,
|
||||||
|
sup.SupplierPhone,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
ac.PurchaseOrderAssetContractName AS ContractName,
|
||||||
|
ac.PurchaseOrderAssetContractDate AS ContractDate,
|
||||||
|
ac.PurchaseOrderAssetContractStartDate AS ContractStart,
|
||||||
|
ac.PurchaseOrderAssetContractEndDate AS ContractEnd,
|
||||||
|
ac.PurchaseOrderAssetContractDuration AS ContractDuration,
|
||||||
|
ac.PurchaseOrderAssetContractInstallmentNumber AS InstallmentNumber,
|
||||||
|
ac.PurchaseOrderAssetContractInstallmentPayAmount AS InstallmentPayAmount,
|
||||||
|
ac.PurchaseOrderAssetContractInstallmentDownPayment AS InstallmentDownPayment,
|
||||||
|
ac.PurchaseOrderAssetContractInstallmentDownPaymentType AS InstallmentDownPaymentType,
|
||||||
|
ac.PurchaseOrderAssetContractStatus AS ContractStatus
|
||||||
|
FROM purchase_order po
|
||||||
|
LEFT JOIN supplier sup ON sup.SupplierID = po.PurchaseOrderSupplierID
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = po.PurchaseOrderS_RegionalID
|
||||||
|
LEFT JOIN purchase_order_asset_contract ac ON ac.PurchaseOrderAssetContractPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
AND ac.PurchaseOrderAssetContractIsActive = 'Y'
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchID = (
|
||||||
|
-- Cabang pengirim/tujuan diambil dari detail pertama
|
||||||
|
SELECT pod.PurchaseOrderDetailWarehouseID
|
||||||
|
FROM purchase_order_detail pod
|
||||||
|
WHERE pod.PurchaseOrderDetailPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
AND pod.PurchaseOrderDetailIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
WHERE po.PurchaseOrderIsActive = 'Y'
|
||||||
|
AND po.PurchaseOrderID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Purchase Order tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail (menggunakan summary agar teragregasi)
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pos.PurchaseOrderSummaryQty AS RequestQty,
|
||||||
|
pos.PurchaseOrderSummaryPrice AS SupplierPrice,
|
||||||
|
pos.PurchaseOrderSummaryDiscountAmount AS DiskonAmount,
|
||||||
|
pos.PurchaseOrderSummaryTotal AS TempTotal,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM purchase_order_summary pos
|
||||||
|
JOIN m_item item ON item.M_ItemID = pos.PurchaseOrderSummaryItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = pos.PurchaseOrderSummaryItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
WHERE pos.PurchaseOrderSummaryIsActive = 'Y'
|
||||||
|
AND pos.PurchaseOrderSummaryPurchaseOrderID = ?
|
||||||
|
ORDER BY pos.PurchaseOrderSummaryID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PURCHASE ORDER ASET (KONTRAK / CICILAN)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
// Periode kontrak
|
||||||
|
$periodeKontrak = '-';
|
||||||
|
if (!empty($header['ContractStart']) && $header['ContractStart'] !== '0000-00-00') {
|
||||||
|
$periodeKontrak = $this->_fmt_date($header['ContractStart']) . ' s/d ' . $this->_fmt_date($header['ContractEnd']);
|
||||||
|
if (intval($header['ContractDuration']) > 0) {
|
||||||
|
$periodeKontrak .= ' (' . $header['ContractDuration'] . ' Bln)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['PurchaseOrderNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['PurchaseOrderDate']), false),
|
||||||
|
array('Nama Kontrak', $header['ContractName'] ?: '-', false),
|
||||||
|
array('Tanggal Kontrak', $this->_fmt_date($header['ContractDate']), false),
|
||||||
|
array('Periode Kontrak', $periodeKontrak, false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['PurchaseOrderNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['PurchaseOrderNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
// Down Payment format
|
||||||
|
$dpVal = '-';
|
||||||
|
$dpNominal = floatval($header['InstallmentDownPayment'] ?? 0);
|
||||||
|
if ($dpNominal > 0) {
|
||||||
|
if (($header['InstallmentDownPaymentType'] ?? 'nominal') === 'percent') {
|
||||||
|
$dpVal = number_format($dpNominal, 0, ',', '.') . '%';
|
||||||
|
} else {
|
||||||
|
$dpVal = $this->_fmt_rp($dpNominal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cicilan format
|
||||||
|
$installmentVal = '-';
|
||||||
|
$instNum = intval($header['InstallmentNumber'] ?? 0);
|
||||||
|
$instAmount = floatval($header['InstallmentPayAmount'] ?? 0);
|
||||||
|
if ($instNum > 0) {
|
||||||
|
$installmentVal = $instNum . ' Kali x ' . $this->_fmt_rp($instAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Supplier', $header['SupplierName'] ?: '-'),
|
||||||
|
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
|
||||||
|
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
|
||||||
|
array('Down Payment (DP)', $dpVal),
|
||||||
|
array('Cicilan / Tenor', $installmentVal),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Supplier') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 60 + 20 + 15 + 25 + 22 + 30 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 60, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 15, 'R'),
|
||||||
|
array('Harga Satuan', 25, 'R'),
|
||||||
|
array('Diskon', 22, 'R'),
|
||||||
|
array('Total', 30, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$subTotal = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['RequestQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['SupplierPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['DiskonAmount']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['TempTotal']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$subTotal += floatval($d['TempTotal']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
// ── Ringkasan Biaya di Bagian Kanan Bawah ──────────────────────────────
|
||||||
|
$discountPO = floatval($header['PurchaseOrderDiscountAmount'] ?? 0);
|
||||||
|
$ppnAmount = floatval($header['PurchaseOrderTaxAmountPpn'] ?? 0);
|
||||||
|
$pphAmount = floatval($header['PurchaseOrderTaxAmountPph'] ?? 0);
|
||||||
|
$shipCost = floatval($header['PurchaseOrderShippingCost'] ?? 0);
|
||||||
|
$grandTotal = floatval($header['PurchaseOrderGrandTotal'] ?? ($subTotal - $discountPO + $ppnAmount - $pphAmount + $shipCost));
|
||||||
|
|
||||||
|
$summary = array(
|
||||||
|
array('Subtotal', $this->_fmt_rp($subTotal)),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($discountPO > 0) {
|
||||||
|
$summary[] = array('Diskon PO', '-' . $this->_fmt_rp($discountPO));
|
||||||
|
}
|
||||||
|
if ($ppnAmount > 0) {
|
||||||
|
$summary[] = array('PPN', $this->_fmt_rp($ppnAmount));
|
||||||
|
}
|
||||||
|
if ($pphAmount > 0) {
|
||||||
|
$summary[] = array('PPH', '-' . $this->_fmt_rp($pphAmount));
|
||||||
|
}
|
||||||
|
if ($shipCost > 0) {
|
||||||
|
$summary[] = array('Ongkos Kirim', $this->_fmt_rp($shipCost));
|
||||||
|
}
|
||||||
|
$summary[] = array('Grand Total', $this->_fmt_rp($grandTotal));
|
||||||
|
|
||||||
|
$cW1 = 62;
|
||||||
|
$cW2 = 30;
|
||||||
|
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 3), 1)); // Sejajar dengan Qty ke kanan
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
|
||||||
|
if ($s[0] === 'Grand Total') {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
}
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Purchase Order (PO) ini tunduk pada syarat dan ketentuan kontrak sewa/beli aset yang disepakati.',
|
||||||
|
'Seluruh pembayaran DP dan angsuran harus disetorkan tepat waktu sesuai jadwal kontrak.',
|
||||||
|
'Serah terima aset akan didokumentasikan terpisah menggunakan Berita Acara Serah Terima (BAST).',
|
||||||
|
'PO ini sah secara hukum setelah disetujui dan divalidasi secara digital melalui sistem ERP.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
440
application/controllers/report/Rpt_purchase_order_jasa.php
Normal file
440
application/controllers/report/Rpt_purchase_order_jasa.php
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class PurchaseOrderJasaFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_purchase_order_jasa extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var PurchaseOrderJasaFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Purchase Order Jasa Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (PurchaseOrderID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new PurchaseOrderJasaFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'PO_JASA_' . str_replace('/', '-', $header['PurchaseOrderNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
po.*,
|
||||||
|
sup.SupplierName,
|
||||||
|
sup.SupplierAddress,
|
||||||
|
sup.SupplierPhone,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
kj.T_KontrakJasaJenisKontrak AS JenisKontrak,
|
||||||
|
kj.T_KontrakJasaStartDate AS StartDate,
|
||||||
|
kj.T_KontrakJasaEndDate AS EndDate,
|
||||||
|
kj.T_KontrakJasaJumlahPI AS JumlahPI,
|
||||||
|
kj.T_KontrakJasaStatus AS StatusKontrak
|
||||||
|
FROM purchase_order po
|
||||||
|
LEFT JOIN supplier sup ON sup.SupplierID = po.PurchaseOrderSupplierID
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = po.PurchaseOrderS_RegionalID
|
||||||
|
LEFT JOIN t_kontrak_jasa kj ON kj.T_KontrakJasaPurchaseOrderID = po.PurchaseOrderID
|
||||||
|
AND kj.T_KontrakJasaIsActive = 'Y'
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = kj.T_KontrakJasaM_BranchCode
|
||||||
|
WHERE po.PurchaseOrderIsActive = 'Y'
|
||||||
|
AND po.PurchaseOrderID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Purchase Order Jasa tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pos.PurchaseOrderSummaryQty AS RequestQty,
|
||||||
|
pos.PurchaseOrderSummaryPrice AS SupplierPrice,
|
||||||
|
pos.PurchaseOrderSummaryDiscountAmount AS DiskonAmount,
|
||||||
|
pos.PurchaseOrderSummaryTotal AS TempTotal,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM purchase_order_summary pos
|
||||||
|
JOIN m_item item ON item.M_ItemID = pos.PurchaseOrderSummaryItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = pos.PurchaseOrderSummaryItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
WHERE pos.PurchaseOrderSummaryIsActive = 'Y'
|
||||||
|
AND pos.PurchaseOrderSummaryPurchaseOrderID = ?
|
||||||
|
ORDER BY pos.PurchaseOrderSummaryID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PURCHASE ORDER JASA (SERVICE PO)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
// Format Jenis Kontrak
|
||||||
|
$jenisKontrak = '-';
|
||||||
|
if (!empty($header['JenisKontrak'])) {
|
||||||
|
$jenisKontrak = ($header['JenisKontrak'] === 'once') ? 'Sekali Bayar (Once)' : 'Berkala (Recurring)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Periode kontrak
|
||||||
|
$periodeJasa = '-';
|
||||||
|
if (!empty($header['StartDate']) && $header['StartDate'] !== '0000-00-00') {
|
||||||
|
$periodeJasa = $this->_fmt_date($header['StartDate']) . ' s/d ' . $this->_fmt_date($header['EndDate']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jumlah Termin/PI
|
||||||
|
$jumlahPI = '-';
|
||||||
|
if (intval($header['JumlahPI'] ?? 0) > 0) {
|
||||||
|
$jumlahPI = $header['JumlahPI'] . ' Kali Pembayaran';
|
||||||
|
}
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['PurchaseOrderNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['PurchaseOrderDate']), false),
|
||||||
|
array('Cabang', $header['M_BranchName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['PurchaseOrderNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['PurchaseOrderNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Supplier', $header['SupplierName'] ?: '-'),
|
||||||
|
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
|
||||||
|
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
|
||||||
|
array('Jenis Kontrak', $jenisKontrak),
|
||||||
|
array('Periode Jasa', $periodeJasa),
|
||||||
|
array('Termin Bayar', $jumlahPI),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Supplier') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 65 + 20 + 15 + 25 + 22 + 25 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 65, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 15, 'R'),
|
||||||
|
array('Harga Satuan', 25, 'R'),
|
||||||
|
array('Diskon', 22, 'R'),
|
||||||
|
array('Total', 25, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$subTotal = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['RequestQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['SupplierPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['DiskonAmount']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[6][1], 6, $this->_fmt_rp($d['TempTotal']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$subTotal += floatval($d['TempTotal']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
// ── Ringkasan Biaya di Bagian Kanan Bawah ──────────────────────────────
|
||||||
|
$discountPO = floatval($header['PurchaseOrderDiscountAmount'] ?? 0);
|
||||||
|
$ppnAmount = floatval($header['PurchaseOrderTaxAmountPpn'] ?? 0);
|
||||||
|
$pphAmount = floatval($header['PurchaseOrderTaxAmountPph'] ?? 0);
|
||||||
|
$shipCost = floatval($header['PurchaseOrderShippingCost'] ?? 0);
|
||||||
|
$grandTotal = floatval($header['PurchaseOrderGrandTotal'] ?? ($subTotal - $discountPO + $ppnAmount - $pphAmount + $shipCost));
|
||||||
|
|
||||||
|
$summary = array(
|
||||||
|
array('Subtotal', $this->_fmt_rp($subTotal)),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($discountPO > 0) {
|
||||||
|
$summary[] = array('Diskon PO', '-' . $this->_fmt_rp($discountPO));
|
||||||
|
}
|
||||||
|
if ($ppnAmount > 0) {
|
||||||
|
$summary[] = array('PPN', $this->_fmt_rp($ppnAmount));
|
||||||
|
}
|
||||||
|
if ($pphAmount > 0) {
|
||||||
|
$summary[] = array('PPH', '-' . $this->_fmt_rp($pphAmount));
|
||||||
|
}
|
||||||
|
if ($shipCost > 0) {
|
||||||
|
$summary[] = array('Ongkos Kirim', $this->_fmt_rp($shipCost));
|
||||||
|
}
|
||||||
|
$summary[] = array('Grand Total', $this->_fmt_rp($grandTotal));
|
||||||
|
|
||||||
|
$cW1 = 47;
|
||||||
|
$cW2 = 25;
|
||||||
|
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1)); // Sejajar dengan Harga Satuan ke kanan
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
|
||||||
|
if ($s[0] === 'Grand Total') {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
}
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Purchase Order (PO) Jasa ini tunduk pada syarat dan ketentuan kontrak pengerjaan yang disepakati.',
|
||||||
|
'Seluruh termin pembayaran angsuran jasa harus ditagihkan disertai dengan Berita Acara Serah Terima Jasa (BASTJ).',
|
||||||
|
'Klaim ketidaksesuaian hasil pengerjaan harus dilaporkan langsung ke vendor bersangkutan.',
|
||||||
|
'PO ini sah secara hukum setelah disetujui dan divalidasi secara digital melalui sistem ERP.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
431
application/controllers/report/Rpt_receive_item_po.php
Normal file
431
application/controllers/report/Rpt_receive_item_po.php
Normal file
@@ -0,0 +1,431 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal.
|
||||||
|
// =============================================================================
|
||||||
|
class ReceiveItemPoFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_receive_item_po extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var ReceiveItemPoFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Receive Item PO (Persediaan) Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (ReceiveOrderPoID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new ReceiveItemPoFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'RI_PO_' . str_replace('/', '-', $header['ReceiveOrderPoNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
rop.*,
|
||||||
|
sup.SupplierName,
|
||||||
|
sup.SupplierAddress,
|
||||||
|
sup.SupplierPhone,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
wh.WarehouseName AS ReceivedWarehouseName,
|
||||||
|
IFNULL(uCr.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(uCf.M_UserUsername, '') AS ConfirmedByName,
|
||||||
|
IFNULL((
|
||||||
|
SELECT po.PurchaseOrderShippingCost
|
||||||
|
FROM receive_order_po_detail d
|
||||||
|
JOIN purchase_order po ON po.PurchaseOrderID = d.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE d.ReceiveOrderPoDetailReceiveOrderPoID = rop.ReceiveOrderPoID
|
||||||
|
AND d.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
), 0) AS PoShippingCostAmount,
|
||||||
|
IFNULL((
|
||||||
|
SELECT po.PurchaseOrderShippingCostStatus
|
||||||
|
FROM receive_order_po_detail d
|
||||||
|
JOIN purchase_order po ON po.PurchaseOrderID = d.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE d.ReceiveOrderPoDetailReceiveOrderPoID = rop.ReceiveOrderPoID
|
||||||
|
AND d.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
), 'N') AS PoShippingCostIsPaid
|
||||||
|
FROM receive_order_po rop
|
||||||
|
LEFT JOIN supplier sup ON sup.SupplierID = rop.ReceiveOrderPoSupplierID
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = rop.ReceiveOrderPoM_BranchCode
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = rop.ReceiveOrderPoS_RegionalID
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = rop.ReceiveOrderPoWarehouseID
|
||||||
|
LEFT JOIN m_user uCr ON uCr.M_UserID = rop.ReceiveOrderPoCreatedUserID
|
||||||
|
LEFT JOIN m_user uCf ON uCf.M_UserID = rop.ReceiveOrderPoConfirmedUserID
|
||||||
|
WHERE rop.ReceiveOrderPoIsActive = 'Y'
|
||||||
|
AND rop.ReceiveOrderPoID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Penerimaan PO tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
ropd.*,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
po.PurchaseOrderNumber
|
||||||
|
FROM receive_order_po_detail ropd
|
||||||
|
JOIN m_item item ON item.M_ItemID = ropd.ReceiveOrderPoItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = ropd.ReceiveOrderPoItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_order po ON po.PurchaseOrderID = ropd.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE ropd.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
AND ropd.ReceiveOrderPoDetailReceiveOrderPoID = ?
|
||||||
|
ORDER BY ropd.ReceiveOrderPoDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PENERIMAAN BARANG PO (RECEIVE PO)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['ReceiveOrderPoNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
|
||||||
|
array('No. Surat Jalan', $header['ReceiveOrderPoDONumber'] ?: '-', false),
|
||||||
|
array('Gudang Penerima', $header['ReceivedWarehouseName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['ReceiveOrderPoNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['ReceiveOrderPoNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Supplier', $header['SupplierName'] ?: '-'),
|
||||||
|
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
|
||||||
|
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
|
||||||
|
array('Alamat Penerima', $header['M_BranchAddress'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Supplier' || $item[0] === 'Alamat Penerima') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 75 + 23 + 15 + 27 + 32 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 75, 'L'),
|
||||||
|
array('Unit', 23, 'C'),
|
||||||
|
array('Qty', 15, 'C'),
|
||||||
|
array('Harga', 27, 'R'),
|
||||||
|
array('Total', 32, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$grand_tot = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$grand_tot += floatval($d['ReceiveOrderPoDetailTotal']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($grand_tot), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln(6);
|
||||||
|
|
||||||
|
// Ringkasan Biaya jika ada Biaya Ekspedisi (mendukung fallback dari PO)
|
||||||
|
$shippingCost = floatval($header['ReceiveOrderShippingCostAmount'] ?? 0);
|
||||||
|
$isPaid = $header['ReceiveOrderShippingCostIsPaid'] ?? 'N';
|
||||||
|
|
||||||
|
if ($shippingCost <= 0) {
|
||||||
|
$shippingCost = floatval($header['PoShippingCostAmount'] ?? 0);
|
||||||
|
$isPaid = $header['PoShippingCostIsPaid'] ?? 'N';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($shippingCost > 0) {
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$grandTotal = $grand_tot + $shippingCost;
|
||||||
|
$statusPaid = ($isPaid === 'Y') ? ' (Lunas)' : ' (Belum Lunas)';
|
||||||
|
$summary = array(
|
||||||
|
array('Total Item', $this->_fmt_rp($grand_tot)),
|
||||||
|
array('Biaya Ekspedisi' . $statusPaid, $this->_fmt_rp($shippingCost)),
|
||||||
|
array('Grand Total', $this->_fmt_rp($grandTotal)),
|
||||||
|
);
|
||||||
|
|
||||||
|
$cW1 = 27;
|
||||||
|
$cW2 = 32;
|
||||||
|
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1));
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Barang yang diterima telah dicocokkan dengan Surat Jalan supplier dan Purchase Order asli.',
|
||||||
|
'Segala klaim ketidaksesuaian jumlah atau jenis barang harus diselesaikan langsung dengan supplier bersangkutan.',
|
||||||
|
'Penerimaan barang ini akan otomatis memperbarui stok/inventori gudang persediaan.',
|
||||||
|
'Dokumen ini dicetak secara otomatis dan sah sebagai bukti penerimaan barang masuk.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,435 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class ReceiveItemPoInventarisFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_receive_item_po_inventaris extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var ReceiveItemPoInventarisFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Receive Item PO (Inventaris) Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (ReceiveOrderPoID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new ReceiveItemPoInventarisFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'RI_PO_INV_' . str_replace('/', '-', $header['ReceiveOrderPoNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
rop.*,
|
||||||
|
sup.SupplierName,
|
||||||
|
sup.SupplierAddress,
|
||||||
|
sup.SupplierPhone,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
wh.WarehouseName AS ReceivedWarehouseName,
|
||||||
|
ru.M_RuanganName AS RuanganName,
|
||||||
|
IFNULL(uCr.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(uCf.M_UserUsername, '') AS ConfirmedByName,
|
||||||
|
IFNULL((
|
||||||
|
SELECT po.PurchaseOrderShippingCost
|
||||||
|
FROM receive_order_po_detail d
|
||||||
|
JOIN purchase_order po ON po.PurchaseOrderID = d.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE d.ReceiveOrderPoDetailReceiveOrderPoID = rop.ReceiveOrderPoID
|
||||||
|
AND d.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
), 0) AS PoShippingCostAmount,
|
||||||
|
IFNULL((
|
||||||
|
SELECT po.PurchaseOrderShippingCostStatus
|
||||||
|
FROM receive_order_po_detail d
|
||||||
|
JOIN purchase_order po ON po.PurchaseOrderID = d.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE d.ReceiveOrderPoDetailReceiveOrderPoID = rop.ReceiveOrderPoID
|
||||||
|
AND d.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
), 'N') AS PoShippingCostIsPaid
|
||||||
|
FROM receive_order_po rop
|
||||||
|
LEFT JOIN supplier sup ON sup.SupplierID = rop.ReceiveOrderPoSupplierID
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = rop.ReceiveOrderPoM_BranchCode
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = rop.ReceiveOrderPoS_RegionalID
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = rop.ReceiveOrderPoWarehouseID
|
||||||
|
LEFT JOIN asset_handover ah ON ah.AssetHandoverReceiveOrderPoID = rop.ReceiveOrderPoID
|
||||||
|
AND ah.AssetHandoverIsActive = 'Y'
|
||||||
|
LEFT JOIN m_ruangan ru ON ru.M_RuanganID = ah.AssetHandoverM_RuanganID
|
||||||
|
LEFT JOIN m_user uCr ON uCr.M_UserID = rop.ReceiveOrderPoCreatedUserID
|
||||||
|
LEFT JOIN m_user uCf ON uCf.M_UserID = rop.ReceiveOrderPoConfirmedUserID
|
||||||
|
WHERE rop.ReceiveOrderPoIsActive = 'Y'
|
||||||
|
AND rop.ReceiveOrderPoID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Penerimaan PO tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
ropd.*,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
po.PurchaseOrderNumber
|
||||||
|
FROM receive_order_po_detail ropd
|
||||||
|
JOIN m_item item ON item.M_ItemID = ropd.ReceiveOrderPoItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = ropd.ReceiveOrderPoItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_order po ON po.PurchaseOrderID = ropd.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE ropd.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
AND ropd.ReceiveOrderPoDetailReceiveOrderPoID = ?
|
||||||
|
ORDER BY ropd.ReceiveOrderPoDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PENERIMAAN BARANG PO INVENTARIS (RECEIVE PO)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['ReceiveOrderPoNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
|
||||||
|
array('Gudang Penerima', $header['ReceivedWarehouseName'] ?: '-', false),
|
||||||
|
array('Ruangan / Lokasi', $header['RuanganName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Ruangan (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['ReceiveOrderPoNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['ReceiveOrderPoNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Supplier', $header['SupplierName'] ?: '-'),
|
||||||
|
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
|
||||||
|
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
|
||||||
|
array('Cabang', $header['M_BranchName'] ?: '-'),
|
||||||
|
array('Alamat Penerima', $header['M_BranchAddress'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Supplier' || $item[0] === 'Alamat Penerima') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 75 + 23 + 15 + 27 + 32 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 75, 'L'),
|
||||||
|
array('Unit', 23, 'C'),
|
||||||
|
array('Qty', 15, 'C'),
|
||||||
|
array('Harga', 27, 'R'),
|
||||||
|
array('Total', 32, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$grand_tot = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$grand_tot += floatval($d['ReceiveOrderPoDetailTotal']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($grand_tot), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln(6);
|
||||||
|
|
||||||
|
// Ringkasan Biaya jika ada Biaya Ekspedisi (mendukung fallback dari PO)
|
||||||
|
$shippingCost = floatval($header['ReceiveOrderShippingCostAmount'] ?? 0);
|
||||||
|
$isPaid = $header['ReceiveOrderShippingCostIsPaid'] ?? 'N';
|
||||||
|
|
||||||
|
if ($shippingCost <= 0) {
|
||||||
|
$shippingCost = floatval($header['PoShippingCostAmount'] ?? 0);
|
||||||
|
$isPaid = $header['PoShippingCostIsPaid'] ?? 'N';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($shippingCost > 0) {
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$grandTotal = $grand_tot + $shippingCost;
|
||||||
|
$statusPaid = ($isPaid === 'Y') ? ' (Lunas)' : ' (Belum Lunas)';
|
||||||
|
$summary = array(
|
||||||
|
array('Total Item', $this->_fmt_rp($grand_tot)),
|
||||||
|
array('Biaya Ekspedisi' . $statusPaid, $this->_fmt_rp($shippingCost)),
|
||||||
|
array('Grand Total', $this->_fmt_rp($grandTotal)),
|
||||||
|
);
|
||||||
|
|
||||||
|
$cW1 = 27;
|
||||||
|
$cW2 = 32;
|
||||||
|
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1));
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Barang inventaris/aset yang diterima telah dicocokkan dengan fisik barang dan Purchase Order asli.',
|
||||||
|
'Penempatan barang inventaris/aset disesuaikan dengan Ruangan/Lokasi yang tertera di dokumen ini.',
|
||||||
|
'Penerimaan barang inventaris/aset ini akan otomatis didaftarkan ke sistem manajemen aset perusahaan.',
|
||||||
|
'Dokumen ini dicetak secara otomatis dan sah sebagai bukti penerimaan barang masuk.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
509
application/controllers/report/Rpt_receive_order_asset.php
Normal file
509
application/controllers/report/Rpt_receive_order_asset.php
Normal file
@@ -0,0 +1,509 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class ReceiveOrderAssetFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_receive_order_asset extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var ReceiveOrderAssetFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Receive Order Asset Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (ReceiveOrderPoID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new ReceiveOrderAssetFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_inspeksi($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'RI_PO_ASSET_' . str_replace('/', '-', $header['ReceiveOrderPoNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
rop.*,
|
||||||
|
sup.SupplierName,
|
||||||
|
sup.SupplierAddress,
|
||||||
|
sup.SupplierPhone,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
wh.WarehouseName AS ReceivedWarehouseName,
|
||||||
|
IFNULL(uCr.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(uCf.M_UserUsername, '') AS ConfirmedByName,
|
||||||
|
IFNULL((
|
||||||
|
SELECT po.PurchaseOrderShippingCost
|
||||||
|
FROM receive_order_po_detail d
|
||||||
|
JOIN purchase_order po ON po.PurchaseOrderID = d.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE d.ReceiveOrderPoDetailReceiveOrderPoID = rop.ReceiveOrderPoID
|
||||||
|
AND d.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
), 0) AS PoShippingCostAmount,
|
||||||
|
IFNULL((
|
||||||
|
SELECT po.PurchaseOrderShippingCostStatus
|
||||||
|
FROM receive_order_po_detail d
|
||||||
|
JOIN purchase_order po ON po.PurchaseOrderID = d.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
WHERE d.ReceiveOrderPoDetailReceiveOrderPoID = rop.ReceiveOrderPoID
|
||||||
|
AND d.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
), 'N') AS PoShippingCostIsPaid
|
||||||
|
FROM receive_order_po rop
|
||||||
|
LEFT JOIN supplier sup ON sup.SupplierID = rop.ReceiveOrderPoSupplierID
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = rop.ReceiveOrderPoM_BranchCode
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = rop.ReceiveOrderPoS_RegionalID
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = rop.ReceiveOrderPoWarehouseID
|
||||||
|
LEFT JOIN m_user uCr ON uCr.M_UserID = rop.ReceiveOrderPoCreatedUserID
|
||||||
|
LEFT JOIN m_user uCf ON uCf.M_UserID = rop.ReceiveOrderPoConfirmedUserID
|
||||||
|
WHERE rop.ReceiveOrderPoIsActive = 'Y'
|
||||||
|
AND rop.ReceiveOrderPoID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Penerimaan PO tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
ropd.*,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
po.PurchaseOrderNumber,
|
||||||
|
uP.M_UserUsername AS StaffPenerima,
|
||||||
|
insp.ReceiveOrderPoInspeksiPengirim AS StaffPengirim,
|
||||||
|
insp.ReceiveOrderPoInspeksiKeadaanKemasan AS KeadaanKemasan,
|
||||||
|
insp.ReceiveOrderPoInspeksiKondisiPengiriman AS KondisiPengiriman,
|
||||||
|
insp.ReceiveOrderPoInspeksiSimpulan AS Simpulan,
|
||||||
|
insp.ReceiveOrderPoInspeksiCatatan AS CatatanInspeksi
|
||||||
|
FROM receive_order_po_detail ropd
|
||||||
|
JOIN m_item item ON item.M_ItemID = ropd.ReceiveOrderPoItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = ropd.ReceiveOrderPoItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_order po ON po.PurchaseOrderID = ropd.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
LEFT JOIN receive_order_po_inspeksi insp ON insp.ReceiveOrderPoInspeksiReceiveOrderPoDetailID = ropd.ReceiveOrderPoDetailID
|
||||||
|
AND insp.ReceiveOrderPoInspeksiIsActive = 'Y'
|
||||||
|
LEFT JOIN m_user uP ON uP.M_UserID = insp.ReceiveOrderPoInspeksiStaffPenerimaID
|
||||||
|
WHERE ropd.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
AND ropd.ReceiveOrderPoDetailReceiveOrderPoID = ?
|
||||||
|
ORDER BY ropd.ReceiveOrderPoDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'PENERIMAAN BARANG PO ASET (RECEIVE PO ASSET)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['ReceiveOrderPoNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
|
||||||
|
array('Gudang Penerima', $header['ReceivedWarehouseName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Ruangan (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['ReceiveOrderPoNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['ReceiveOrderPoNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Supplier', $header['SupplierName'] ?: '-'),
|
||||||
|
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
|
||||||
|
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
|
||||||
|
array('Cabang', $header['M_BranchName'] ?: '-'),
|
||||||
|
array('Alamat Penerima', $header['M_BranchAddress'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Supplier' || $item[0] === 'Alamat Penerima') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 75 + 23 + 15 + 27 + 32 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 75, 'L'),
|
||||||
|
array('Unit', 23, 'C'),
|
||||||
|
array('Qty', 15, 'C'),
|
||||||
|
array('Harga', 27, 'R'),
|
||||||
|
array('Total', 32, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$grand_tot = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['ReceiveOrderPoDetailQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['ReceiveOrderPoDetailTotal']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$grand_tot += floatval($d['ReceiveOrderPoDetailTotal']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($grand_tot), 1, 0, 'R', true);
|
||||||
|
|
||||||
|
// Ringkasan Biaya jika ada Biaya Ekspedisi (mendukung fallback dari PO)
|
||||||
|
$shippingCost = floatval($header['ReceiveOrderShippingCostAmount'] ?? 0);
|
||||||
|
$isPaid = $header['ReceiveOrderShippingCostIsPaid'] ?? 'N';
|
||||||
|
|
||||||
|
if ($shippingCost <= 0) {
|
||||||
|
$shippingCost = floatval($header['PoShippingCostAmount'] ?? 0);
|
||||||
|
$isPaid = $header['PoShippingCostIsPaid'] ?? 'N';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($shippingCost > 0) {
|
||||||
|
$pdf->Ln(7);
|
||||||
|
$grandTotal = $grand_tot + $shippingCost;
|
||||||
|
$statusPaid = ($isPaid === 'Y') ? ' (Lunas)' : ' (Belum Lunas)';
|
||||||
|
$summary = array(
|
||||||
|
array('Total Item', $this->_fmt_rp($grand_tot)),
|
||||||
|
array('Biaya Ekspedisi' . $statusPaid, $this->_fmt_rp($shippingCost)),
|
||||||
|
array('Grand Total', $this->_fmt_rp($grandTotal)),
|
||||||
|
);
|
||||||
|
|
||||||
|
$cW1 = 27;
|
||||||
|
$cW2 = 32;
|
||||||
|
$offsetX = 15 + array_sum(array_column(array_slice($cols, 0, 4), 1));
|
||||||
|
|
||||||
|
foreach ($summary as $s) {
|
||||||
|
$pdf->SetX($offsetX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->Cell($cW1, 5, $s[0], 0, 0, 'L');
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->Cell($cW2, 5, $s[1], 0, 1, 'R');
|
||||||
|
}
|
||||||
|
$pdf->Ln(8);
|
||||||
|
} else {
|
||||||
|
$pdf->Ln(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDF SECTION: Inspeksi & Verifikasi Barang / Aset (Blok Terpisah)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_inspeksi($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
// Cek apakah ada data inspeksi yang terisi
|
||||||
|
$hasInspeksi = false;
|
||||||
|
foreach ($details as $d) {
|
||||||
|
if (!empty($d['Simpulan']) || !empty($d['StaffPenerima']) || !empty($d['CatatanInspeksi'])) {
|
||||||
|
$hasInspeksi = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$hasInspeksi) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
||||||
|
$pdf->Cell($pageW, 6, 'DETAIL HASIL INSPEKSI BARANG / ASET', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$no = 1;
|
||||||
|
foreach ($details as $d) {
|
||||||
|
// Lewati jika item ini tidak memiliki data inspeksi sama sekali
|
||||||
|
if (empty($d['Simpulan']) && empty($d['StaffPenerima']) && empty($d['CatatanInspeksi'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, $no . '. ' . ($d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-')), 0, 1, 'L');
|
||||||
|
|
||||||
|
// Indentasi isi detail inspeksi
|
||||||
|
$lblW = 32;
|
||||||
|
$valW = $pageW - $lblW - 4;
|
||||||
|
|
||||||
|
$items = array(
|
||||||
|
array('Staff Penerima', $d['StaffPenerima'] ?: '-'),
|
||||||
|
array('Kurir Pengirim', $d['StaffPengirim'] ?: '-'),
|
||||||
|
array('Keadaan Kemasan', $d['KeadaanKemasan'] ?: '-'),
|
||||||
|
array('Kondisi Pengiriman', $d['KondisiPengiriman'] ?: '-'),
|
||||||
|
array('Simpulan Hasil', $d['Simpulan'] ?: '-'),
|
||||||
|
array('Catatan Inspeksi', $d['CatatanInspeksi'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$pdf->SetX(18); // Indent slightly to the right
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$pdf->SetDrawColor(200, 200, 200);
|
||||||
|
$pdf->SetLineWidth(0.1);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0); // restore black
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Barang aset yang diterima telah dicocokkan dengan fisik barang dan Purchase Order asli.',
|
||||||
|
'Penempatan barang aset disesuaikan dengan Ruangan/Lokasi yang tertera di dokumen ini.',
|
||||||
|
'Penerimaan barang aset ini akan otomatis didaftarkan ke sistem manajemen aset perusahaan.',
|
||||||
|
'Dokumen ini dicetak secara otomatis dan sah sebagai bukti penerimaan barang masuk.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
600
application/controllers/report/Rpt_receive_order_jasa.php
Normal file
600
application/controllers/report/Rpt_receive_order_jasa.php
Normal file
@@ -0,0 +1,600 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class ReceiveOrderJasaFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
// Properties untuk tabel multiline
|
||||||
|
public $widths;
|
||||||
|
public $aligns;
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetWidths($w)
|
||||||
|
{
|
||||||
|
$this->widths = $w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetAligns($a)
|
||||||
|
{
|
||||||
|
$this->aligns = $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Row($data, $fill = false, $h = 6)
|
||||||
|
{
|
||||||
|
// Hitung tinggi maksimum baris berdasarkan multiline
|
||||||
|
$nb = 0;
|
||||||
|
for ($i = 0; $i < count($data); $i++) {
|
||||||
|
$nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
|
||||||
|
}
|
||||||
|
$rowH = $h * $nb;
|
||||||
|
|
||||||
|
// Cek apakah perlu ganti halaman secara otomatis
|
||||||
|
$this->CheckPageBreak($rowH);
|
||||||
|
|
||||||
|
// Gambar cell pada baris
|
||||||
|
for ($i = 0; $i < count($data); $i++) {
|
||||||
|
$w = $this->widths[$i];
|
||||||
|
$a = isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
|
||||||
|
|
||||||
|
$x = $this->GetX();
|
||||||
|
$y = $this->GetY();
|
||||||
|
|
||||||
|
// Gambar border dan background
|
||||||
|
$this->Rect($x, $y, $w, $rowH, $fill ? 'DF' : 'D');
|
||||||
|
// Tulis teks menggunakan MultiCell
|
||||||
|
$this->MultiCell($w, $h, $data[$i], 0, $a);
|
||||||
|
// Geser posisi X ke kanan untuk cell berikutnya
|
||||||
|
$this->SetXY($x + $w, $y);
|
||||||
|
}
|
||||||
|
// Pindah baris
|
||||||
|
$this->Ln($rowH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CheckPageBreak($h)
|
||||||
|
{
|
||||||
|
// Jika tinggi baris melewati batas, buat halaman baru
|
||||||
|
if ($this->GetY() + $h > $this->PageBreakTrigger) {
|
||||||
|
$this->AddPage($this->CurOrientation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function NbLines($w, $txt)
|
||||||
|
{
|
||||||
|
// Menghitung jumlah baris yang akan dihasilkan oleh MultiCell
|
||||||
|
$cw = &$this->CurrentFont['cw'];
|
||||||
|
if ($w == 0) {
|
||||||
|
$w = $this->w - $this->rMargin - $this->x;
|
||||||
|
}
|
||||||
|
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
|
||||||
|
$s = str_replace("\r", '', $txt);
|
||||||
|
$nb = strlen($s);
|
||||||
|
if ($nb > 0 && $s[$nb - 1] == "\n") {
|
||||||
|
$nb--;
|
||||||
|
}
|
||||||
|
$sep = -1;
|
||||||
|
$i = 0;
|
||||||
|
$j = 0;
|
||||||
|
$l = 0;
|
||||||
|
$nl = 1;
|
||||||
|
while ($i < $nb) {
|
||||||
|
$c = $s[$i];
|
||||||
|
if ($c == "\n") {
|
||||||
|
$i++;
|
||||||
|
$sep = -1;
|
||||||
|
$j = $i;
|
||||||
|
$l = 0;
|
||||||
|
$nl++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($c == ' ') {
|
||||||
|
$sep = $i;
|
||||||
|
}
|
||||||
|
$l += $cw[$c];
|
||||||
|
if ($l > $wmax) {
|
||||||
|
if ($sep == -1) {
|
||||||
|
if ($i == $j) {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$i = $sep + 1;
|
||||||
|
}
|
||||||
|
$sep = -1;
|
||||||
|
$j = $i;
|
||||||
|
$l = 0;
|
||||||
|
$nl++;
|
||||||
|
} else {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_receive_order_jasa extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var ReceiveOrderJasaFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Receive Order Jasa Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (ReceiveOrderPoID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new ReceiveOrderJasaFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_inspeksi($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'RO_JASA_' . str_replace('/', '-', $header['ReceiveOrderPoNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
ro.ReceiveOrderPoID,
|
||||||
|
ro.ReceiveOrderPoNumber,
|
||||||
|
ro.ReceiveOrderPoIDate,
|
||||||
|
ro.ReceiveOrderPoRefNumber,
|
||||||
|
ro.ReceiveOrderPoNote,
|
||||||
|
ro.ReceiveOrderPoConfirmed,
|
||||||
|
sup.SupplierName,
|
||||||
|
sup.SupplierAddress,
|
||||||
|
sup.SupplierPhone,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
po.PurchaseOrderNumber,
|
||||||
|
kj.T_KontrakJasaJenisKontrak AS JenisKontrak,
|
||||||
|
kj.T_KontrakJasaStartDate AS StartDate,
|
||||||
|
kj.T_KontrakJasaEndDate AS EndDate,
|
||||||
|
kj.T_KontrakJasaJumlahPI AS JumlahPI,
|
||||||
|
kj.T_KontrakJasaUsedCount AS UsedCount
|
||||||
|
FROM receive_order_po ro
|
||||||
|
JOIN receive_order_po_detail rod ON rod.ReceiveOrderPoDetailReceiveOrderPoID = ro.ReceiveOrderPoID
|
||||||
|
AND rod.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_order po ON po.PurchaseOrderID = rod.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
LEFT JOIN supplier sup ON sup.SupplierID = ro.ReceiveOrderPoSupplierID
|
||||||
|
LEFT JOIN t_kontrak_jasa kj ON kj.T_KontrakJasaPurchaseOrderID = rod.ReceiveOrderPoDetailPurchaseOrderID
|
||||||
|
AND kj.T_KontrakJasaM_BranchCode = ro.ReceiveOrderPoM_BranchCode
|
||||||
|
AND kj.T_KontrakJasaIsActive = 'Y'
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = ro.ReceiveOrderPoM_BranchCode
|
||||||
|
WHERE ro.ReceiveOrderPoIsActive = 'Y'
|
||||||
|
AND ro.ReceiveOrderPoID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Receive Order Jasa tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
rod.ReceiveOrderPoDetailID,
|
||||||
|
rod.ReceiveOrderPoDetailQty AS Qty,
|
||||||
|
rod.ReceiveOrderPoDetailPrice AS Price,
|
||||||
|
(rod.ReceiveOrderPoDetailQty * rod.ReceiveOrderPoDetailPrice) AS TotalPrice,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
insp.OrderJasaInspeksiHasilPengerjaan AS HasilPengerjaan,
|
||||||
|
insp.OrderJasaInspeksiCatatanPengerjaan AS CatatanPengerjaan,
|
||||||
|
insp.OrderJasaInspeksiKesimpulan AS Kesimpulan,
|
||||||
|
insp.OrderJasaInspeksiCatatan AS CatatanKesimpulan,
|
||||||
|
insp.OrderJasaInspeksiPetugasPengerjaan AS Pekerja,
|
||||||
|
uP.M_UserUsername AS PemeriksaName
|
||||||
|
FROM receive_order_po_detail rod
|
||||||
|
JOIN m_item item ON item.M_ItemID = rod.ReceiveOrderPoItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = rod.ReceiveOrderPoItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
LEFT JOIN order_jasa_inspeksi insp ON insp.OrderJasaInspeksiReceiveOrderPoDetailID = rod.ReceiveOrderPoDetailID
|
||||||
|
AND insp.OrderJasaInspeksiIsActive = 'Y'
|
||||||
|
LEFT JOIN m_user uP ON uP.M_UserID = insp.OrderJasaInspeksiStaffPemeriksaID
|
||||||
|
WHERE rod.ReceiveOrderPoDetailIsActive = 'Y'
|
||||||
|
AND rod.ReceiveOrderPoDetailReceiveOrderPoID = ?
|
||||||
|
ORDER BY rod.ReceiveOrderPoDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'TANDA TERIMA JASA (RECEIVE ORDER SERVICE)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
// Format Jenis Kontrak
|
||||||
|
$jenisKontrak = '-';
|
||||||
|
if (!empty($header['JenisKontrak'])) {
|
||||||
|
$jenisKontrak = ($header['JenisKontrak'] === 'once') ? 'Sekali Bayar (Once)' : 'Berkala (Recurring)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Periode kontrak
|
||||||
|
$periodeJasa = '-';
|
||||||
|
if (!empty($header['StartDate']) && $header['StartDate'] !== '0000-00-00') {
|
||||||
|
$periodeJasa = $this->_fmt_date($header['StartDate']) . ' s/d ' . $this->_fmt_date($header['EndDate']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Termin / usedcount
|
||||||
|
$terminInfo = '-';
|
||||||
|
if (intval($header['JumlahPI'] ?? 0) > 0) {
|
||||||
|
$terminInfo = "Termin ke-" . ($header['UsedCount'] ?? 0) . " dari " . $header['JumlahPI'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['ReceiveOrderPoNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['ReceiveOrderPoIDate']), false),
|
||||||
|
array('Cabang', $header['M_BranchName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['ReceiveOrderPoNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['ReceiveOrderPoNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Supplier', $header['SupplierName'] ?: '-'),
|
||||||
|
array('Alamat Supplier', $header['SupplierAddress'] ?: '-'),
|
||||||
|
array('Telp Supplier', $header['SupplierPhone'] ?: '-'),
|
||||||
|
array('Jenis Kontrak', $jenisKontrak),
|
||||||
|
array('Periode Jasa', $periodeJasa),
|
||||||
|
array('Termin Realisasi', $terminInfo),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Supplier') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 75 + 20 + 15 + 30 + 32 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 75, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 15, 'C'),
|
||||||
|
array('Harga', 30, 'R'),
|
||||||
|
array('Total', 32, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Set lebar dan alignment kolom untuk metode Row()
|
||||||
|
$pdf->SetWidths(array_column($cols, 1));
|
||||||
|
$pdf->SetAligns(array_column($cols, 2));
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$totalPay = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$row_data = array(
|
||||||
|
$no,
|
||||||
|
$d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'),
|
||||||
|
$d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'),
|
||||||
|
$this->_fmt_qty($d['Qty']),
|
||||||
|
$this->_fmt_rp($d['Price']),
|
||||||
|
$this->_fmt_rp($d['TotalPrice']),
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->Row($row_data);
|
||||||
|
|
||||||
|
$totalPay += floatval($d['TotalPrice']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($totalPay), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Inspeksi & Verifikasi Jasa (Blok Terpisah)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_inspeksi($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
// Cek apakah ada data inspeksi yang terisi
|
||||||
|
$hasInspeksi = false;
|
||||||
|
foreach ($details as $d) {
|
||||||
|
if (!empty($d['HasilPengerjaan']) || !empty($d['Kesimpulan']) || !empty($d['Pekerja'])) {
|
||||||
|
$hasInspeksi = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$hasInspeksi) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 10);
|
||||||
|
$pdf->Cell($pageW, 6, 'DETAIL HASIL INSPEKSI & VERIFIKASI JASA', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$no = 1;
|
||||||
|
foreach ($details as $d) {
|
||||||
|
// Lewati jika item ini tidak memiliki data inspeksi sama sekali
|
||||||
|
if (empty($d['HasilPengerjaan']) && empty($d['Kesimpulan']) && empty($d['Pekerja'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, $no . '. ' . ($d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-')), 0, 1, 'L');
|
||||||
|
|
||||||
|
// Indentasi isi detail inspeksi
|
||||||
|
$lblW = 32;
|
||||||
|
$valW = $pageW - $lblW - 4;
|
||||||
|
|
||||||
|
$items = array(
|
||||||
|
array('Petugas Pengerjaan', $d['Pekerja'] ?: '-'),
|
||||||
|
array('Staff Pemeriksa', $d['PemeriksaName'] ?: '-'),
|
||||||
|
array('Hasil Pengerjaan', $d['HasilPengerjaan'] ?: '-'),
|
||||||
|
array('Catatan Pengerjaan', $d['CatatanPengerjaan'] ?: '-'),
|
||||||
|
array('Kesimpulan Hasil', $d['Kesimpulan'] ?: '-'),
|
||||||
|
array('Catatan Pemeriksa', $d['CatatanKesimpulan'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$pdf->SetX(18); // Indent slightly to the right
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$pdf->SetDrawColor(200, 200, 200);
|
||||||
|
$pdf->SetLineWidth(0.1);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0); // restore black
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Penerimaan pengerjaan jasa ini berdasarkan hasil verifikasi/inspeksi petugas di lapangan.',
|
||||||
|
'Tanda Terima Jasa (TTJ) ini sah untuk digunakan sebagai lampiran dokumen penagihan vendor.',
|
||||||
|
'Jika terdapat komplain/ketidaksesuaian hasil pengerjaan di kemudian hari, harap merujuk ke Berita Acara inspeksi.',
|
||||||
|
'Dokumen ini dicetak dan divalidasi secara otomatis melalui sistem ERP.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
391
application/controllers/report/Rpt_receive_transfer.php
Normal file
391
application/controllers/report/Rpt_receive_transfer.php
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal.
|
||||||
|
// =============================================================================
|
||||||
|
class ReceiveTransferFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_receive_transfer extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var ReceiveTransferFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Receive Transfer Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (SuratJalanID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new ReceiveTransferFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'RT_' . str_replace('/', '-', $header['SuratJalanNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
sj.*,
|
||||||
|
ex.ExpeditionName,
|
||||||
|
ex.ExpeditionIsInternal,
|
||||||
|
exs.ExpeditionStaffName,
|
||||||
|
exs.ExpeditionStaffMobile,
|
||||||
|
tg.T_GoodsTransferNum,
|
||||||
|
tg.T_GoodsTransferDate,
|
||||||
|
tg.T_GoodsTransferType,
|
||||||
|
tg.T_GoodsTransferFromM_BranchCode,
|
||||||
|
tg.T_GoodsTransferToM_BranchCode,
|
||||||
|
rFrom.S_RegionalName AS RegionalFromName,
|
||||||
|
bTo.M_BranchName AS BranchToName,
|
||||||
|
bTo.M_BranchAddress AS BranchToAddress,
|
||||||
|
wh.WarehouseName AS ReceivedWarehouseName,
|
||||||
|
IFNULL(uRec.M_UserUsername, '') AS ReceivedByName
|
||||||
|
FROM suratjalan sj
|
||||||
|
LEFT JOIN t_goods_transfer tg ON tg.T_GoodsTransferID = sj.SuratJalanT_GoodsTransferID
|
||||||
|
AND tg.T_GoodsTransferIsActive = 'Y'
|
||||||
|
LEFT JOIN expedition ex ON ex.ExpeditionID = sj.SuratJalanEkspedisiID
|
||||||
|
AND ex.ExpeditionIsActive = 'Y'
|
||||||
|
LEFT JOIN expeditionstaff exs ON exs.ExpeditionStaffID = sj.SuratJalanEkspedisiStaffID
|
||||||
|
AND exs.ExpeditionStaffIsActive = 'Y'
|
||||||
|
LEFT JOIN s_regional rFrom ON rFrom.S_RegionalID = tg.T_GoodsTransferFromS_RegionalID
|
||||||
|
LEFT JOIN m_branch bTo ON bTo.M_BranchCode = tg.T_GoodsTransferToM_BranchCode
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = sj.SuratJalanReceivedWarehouseID
|
||||||
|
LEFT JOIN m_user uRec ON uRec.M_UserID = sj.SuratJalanReceivedUserID
|
||||||
|
WHERE sj.SuratJalanIsActive = 'Y'
|
||||||
|
AND sj.SuratJalanID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Penerimaan Surat Jalan tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
sjd.*,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
pr.PurchaseRequestNumber
|
||||||
|
FROM suratjalan_detail sjd
|
||||||
|
JOIN m_item item ON item.M_ItemID = sjd.SuratJalanDetailM_ItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = sjd.SuratJalanDetailItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_request_flag prf ON prf.PurchaseRequestFlagID = sjd.SuratJalanDetailPurchaseRequestFlagID
|
||||||
|
AND prf.PurchaseRequestFlagIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_request_detail prd ON prd.PurchaseRequestDetailID = prf.PurchaseRequestFlagPurchaseRequestDetailID
|
||||||
|
LEFT JOIN purchase_request pr ON pr.PurchaseRequestID = prd.PurchaseRequestDetailPurchaseRequestID
|
||||||
|
WHERE sjd.SuratJalanDetailIsActive = 'Y'
|
||||||
|
AND sjd.SuratJalanDetailSuratJalanID = ?
|
||||||
|
ORDER BY sjd.SuratJalanDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'RECEIVE TRANSFER REPORT (RT)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['SuratJalanNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['SuratJalanDate']), false),
|
||||||
|
array('Tanggal Terima', $this->_fmt_date($header['SuratJalanReceivedDate']), false),
|
||||||
|
array('Gudang Terima', $header['ReceivedWarehouseName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['SuratJalanReceivedNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Catatan Terima', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['SuratJalanReceivedNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Dari Regional', $header['RegionalFromName'] ?: '-'),
|
||||||
|
array('Tujuan Cabang', $header['BranchToName'] ?: '-'),
|
||||||
|
array('Alamat Tujuan', $header['BranchToAddress'] ?: '-'),
|
||||||
|
array('Ekspedisi', $header['ExpeditionName'] ?: '-'),
|
||||||
|
array('Driver / Staf', $header['ExpeditionStaffName'] ?: '-'),
|
||||||
|
array('Diterima Oleh', $header['ReceivedByName'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Tujuan') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 95 + 20 + 20 + 20 + 17 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 95, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty Kirim', 20, 'R'),
|
||||||
|
array('Qty Terima', 20, 'R'),
|
||||||
|
array('Selisih', 17, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$qtyKirim = intval($d['SuratJalanDetailQty']);
|
||||||
|
$qtyTerima = intval($d['SuratJalanDetailQtyReceived']);
|
||||||
|
$selisih = $qtyKirim - $qtyTerima;
|
||||||
|
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qtyKirim), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($qtyTerima), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_qty($selisih), 1, 0, 'C');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Barang yang diterima telah diverifikasi secara kuantitas dan kualitas sesuai dengan fisik yang diserahterimakan.',
|
||||||
|
'Segala ketidaksesuaian/selisih barang harus dilaporkan dalam waktu 1x24 jam sejak dokumen ini ditandatangani.',
|
||||||
|
'Penerimaan barang ini sah secara sistem setelah dokumen ini divalidasi dan disimpan di sistem persediaan.',
|
||||||
|
'Dokumen ini dicetak secara otomatis dari sistem ERP One-API.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
391
application/controllers/report/Rpt_request_mutasi.php
Normal file
391
application/controllers/report/Rpt_request_mutasi.php
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class RequestMutasiFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_request_mutasi extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var RequestMutasiFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Request Mutasi Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (MutasiRequestID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new RequestMutasiFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'RM_' . str_replace('/', '-', $header['MutasiRequestNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
mr.*,
|
||||||
|
ic.itemCategoryID,
|
||||||
|
ic.itemCategoryName,
|
||||||
|
a.M_BranchID AS branch_asal_id,
|
||||||
|
a.M_BranchCode AS branch_asal_code,
|
||||||
|
a.M_BranchName AS branch_asal_name,
|
||||||
|
b.M_BranchID AS branch_tujuan_id,
|
||||||
|
b.M_BranchCode AS branch_tujuan_code,
|
||||||
|
b.M_BranchName AS branch_tujuan_name,
|
||||||
|
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(uv.M_UserUsername, '') AS VerifByName,
|
||||||
|
IFNULL(ua.M_UserUsername, '') AS ApprovedByName
|
||||||
|
FROM mutasi_request mr
|
||||||
|
JOIN item_category ic ON ic.itemCategoryID = mr.MutasiRequestItemCategoryID
|
||||||
|
JOIN m_branch a ON a.M_BranchID = mr.MutasiRequestFromBranchID
|
||||||
|
JOIN m_branch b ON b.M_BranchID = mr.MutasiRequestToBranchID
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = mr.MutasiRequestUserID
|
||||||
|
LEFT JOIN m_user uv ON uv.M_UserID = mr.MutasiRequestVerifUserID
|
||||||
|
LEFT JOIN m_user ua ON ua.M_UserID = mr.MutasiRequestApprovedUserID
|
||||||
|
WHERE mr.MutasiRequestID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Request Mutasi tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
mrd.*,
|
||||||
|
i.M_ItemCode,
|
||||||
|
i.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM mutasi_request_detail mrd
|
||||||
|
LEFT JOIN m_item i ON i.M_ItemID = mrd.MutasiRequestDetailM_ItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = mrd.MutasiRequestDetailItemUnitID
|
||||||
|
WHERE mrd.MutasiRequestDetailMutasiRequestID = ?
|
||||||
|
AND mrd.MutasiRequestDetailIsActive = 'Y'
|
||||||
|
ORDER BY mrd.MutasiRequestDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'REQUEST MUTASI REPORT (RM)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 30;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['MutasiRequestNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['MutasiRequestDate']), false),
|
||||||
|
array('Status', $header['MutasiRequestStatus'], false),
|
||||||
|
array('Kategori', $header['itemCategoryName'], false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan (Note) langsung di bawah Status
|
||||||
|
if (!empty($header['MutasiRequestNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['MutasiRequestNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang Asal', $header['branch_asal_name']),
|
||||||
|
array('Cabang Tujuan', $header['branch_tujuan_name']),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName']),
|
||||||
|
array('Diverifikasi Oleh', $header['VerifByName'] ?: '-'),
|
||||||
|
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tanggal approvals di kolom kanan
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Tgl Verifikasi', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $this->_fmt_datetime($header['MutasiRequestVerifDate']), 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Tgl Approved', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $this->_fmt_datetime($header['MutasiRequestApprovedDate']), 0, 1, 'L');
|
||||||
|
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 80 + 20 + 20 + 25 + 27 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama Item', 80, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 20, 'R'),
|
||||||
|
array('Nilai Buku', 25, 'R'),
|
||||||
|
array('Total', 27, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_val = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['MutasiRequestDetailQty']), 1, 0, 'R');
|
||||||
|
$bookValue = floatval($d['MutasiRequestDetailBookValue'] ?? 0);
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($bookValue), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['MutasiRequestDetailQty'] * $bookValue), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_val += floatval($d['MutasiRequestDetailQty'] * $bookValue);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($total_val), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Mutasi barang ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses mutasi dilakukan.',
|
||||||
|
'Barang yang dimutasi harus sesuai dengan spesifikasi dan jumlah yang tercantum dalam dokumen ini.',
|
||||||
|
'Proses mutasi dilakukan setelah barang diverifikasi dan disetujui oleh pihak terkait.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses mutasi barang.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,410 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// =============================================================================
|
||||||
|
class RequestPengeluaranBarangFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // margin 15+15
|
||||||
|
|
||||||
|
// -- Posisi: 20mm dari bawah halaman ----------------------------------
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// -- Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ---------------
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// -- Baris 2: Tgl Print (kiri) ------------------------------------------
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_request_pengeluaran_barang extends MY_Controller
|
||||||
|
{
|
||||||
|
// -- Properti bersama antar fungsi PDF -------------------------------------
|
||||||
|
/** @var RequestPengeluaranBarangFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Request Pengeluaran Barang Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (RequestItemOutID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Ambil data header & detail dari DB ----------------------------
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// -- Inisialisasi FPDF custom --------------------------------------
|
||||||
|
$this->_pdf = new RequestPengeluaranBarangFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// -- Susun isi halaman ---------------------------------------------
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// -- Output --------------------------------------------------------
|
||||||
|
$filename = 'RIO_' . str_replace('/', '-', $header['RequestItemOutNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
rio.*,
|
||||||
|
wh.WarehouseCode,
|
||||||
|
wh.WarehouseName,
|
||||||
|
wh.WarehouseType,
|
||||||
|
r.S_RegionalName,
|
||||||
|
d.DivisionCode,
|
||||||
|
d.DivisionName,
|
||||||
|
b.M_BranchName AS BranchName,
|
||||||
|
IFNULL(u.M_UserUsername, '') AS CreatedByName,
|
||||||
|
IFNULL(um.M_UserUsername, '') AS ManagerByName,
|
||||||
|
IFNULL(ua.M_UserUsername, '') AS ApprovedByName,
|
||||||
|
IFNULL(uv.M_UserUsername, '') AS VerifiedByName
|
||||||
|
FROM request_item_out rio
|
||||||
|
LEFT JOIN warehouse wh ON wh.WarehouseID = rio.RequestItemOutWarehouseID
|
||||||
|
AND wh.WarehouseIsActive = 'Y'
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = rio.RequestItemOutS_RegionalID
|
||||||
|
AND r.S_RegionalIsActive = 'Y'
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = rio.RequestItemOutM_BranchCode
|
||||||
|
AND b.M_BranchIsActive = 'Y'
|
||||||
|
LEFT JOIN division d ON d.DivisionID = rio.RequestItemOutDivisionID
|
||||||
|
AND d.DivisionIsActive = 'Y'
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = rio.RequestItemOutUserID
|
||||||
|
LEFT JOIN m_user um ON um.M_UserID = rio.RequestItemOutApprovedManagerUserID
|
||||||
|
LEFT JOIN m_user ua ON ua.M_UserID = rio.RequestItemOutApprovedUserID
|
||||||
|
LEFT JOIN m_user uv ON uv.M_UserID = rio.RequestItemOutVerifiedUserID
|
||||||
|
WHERE rio.RequestItemOutID = ?
|
||||||
|
AND rio.RequestItemOutIsActive = 'Y'
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Request Pengeluaran Barang tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
rod.*,
|
||||||
|
i.M_ItemCode,
|
||||||
|
i.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM request_item_out_detail rod
|
||||||
|
LEFT JOIN m_item i ON i.M_ItemID = rod.RequestItemOutDetailM_ItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = rod.RequestItemOutDetailItemUnitID
|
||||||
|
WHERE rod.RequestItemOutDetailRequestItemOutID = ?
|
||||||
|
AND rod.RequestItemOutDetailIsActive = 'Y'
|
||||||
|
ORDER BY rod.RequestItemOutDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// -- Judul utama --------------------------------------------------------
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'REQUEST PENGELUARAN BARANG', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 32;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// -- Kolom Kiri -----------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor Request', $header['RequestItemOutNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['RequestItemOutDate']), false),
|
||||||
|
array('Status', $header['RequestItemOutStatus'], false),
|
||||||
|
array('Divisi', $header['DivisionName'] ?: '-', false),
|
||||||
|
array('Gudang', $header['WarehouseName'] ?: '-', false),
|
||||||
|
array('Regional', $header['S_RegionalName'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan (Note)
|
||||||
|
if (!empty($header['RequestItemOutNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['RequestItemOutNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// -- Kolom Kanan ----------------------------------------------------------
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang', $header['BranchName'] ?: '-'),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName'] ?: '-'),
|
||||||
|
array('Dibuat Tgl', $this->_fmt_datetime($header['RequestItemOutCreated'])),
|
||||||
|
array('Approve Manager', $header['ManagerByName'] ?: '-'),
|
||||||
|
array('Tgl Appr. Manager',$header['RequestItemOutApprovedManagerDate'] ? $this->_fmt_datetime($header['RequestItemOutApprovedManagerDate']) : '-'),
|
||||||
|
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
||||||
|
array('Tgl Disetujui', $header['RequestItemOutApprovedDate'] ? $this->_fmt_datetime($header['RequestItemOutApprovedDate']) : '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifikasi (hanya tampil jika ada)
|
||||||
|
if (!empty($header['RequestItemOutVerifiedDate'])) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Diverifikasi Oleh', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $header['VerifiedByName'] ?: '-', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Tgl Verifikasi', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $this->_fmt_datetime($header['RequestItemOutVerifiedDate']), 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
// -- Definisi kolom: [label, lebar, align] -------------------------------
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 72 + 20 + 25 + 25 + 30 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama Item', 72, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty Request', 25, 'R'),
|
||||||
|
array('Qty Diterima', 25, 'R'),
|
||||||
|
array('Status', 30, 'C'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_qty = 0;
|
||||||
|
$total_recv = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$qty = floatval($d['RequestItemOutDetailQty'] ?? 0);
|
||||||
|
$recvQty = floatval($d['RequestItemOutDetailReceiveQty'] ?? 0);
|
||||||
|
$status = $d['RequestItemOutDetailStatus'] ?? '-';
|
||||||
|
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($qty), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($recvQty), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $status, 1, 0, 'C');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_qty += $qty;
|
||||||
|
$total_recv += $recvQty;
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 3), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[3][1], 7, $this->_fmt_qty($total_qty), 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[4][1], 7, $this->_fmt_qty($total_recv), 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, '', 1, 0, 'C', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Request ini harus disetujui oleh atasan (manager) sebelum diproses lebih lanjut.',
|
||||||
|
'Barang yang diminta akan dikeluarkan sesuai dengan jumlah yang telah disetujui.',
|
||||||
|
'Apabila jumlah barang tidak tersedia, maka akan dilakukan pengeluaran sebagian (partial).',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan administrasi perusahaan.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
370
application/controllers/report/Rpt_stock_request.php
Normal file
370
application/controllers/report/Rpt_stock_request.php
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal.
|
||||||
|
// =============================================================================
|
||||||
|
class StockReqFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_stock_request extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var StockReqFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Stock Request (PR) Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (PurchaseRequestID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new StockReqFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'SR_' . str_replace('/', '-', $header['PurchaseRequestNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pr.*,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
ic.itemCategoryName,
|
||||||
|
IFNULL(u.M_UserUsername,'') AS CreatedByName,
|
||||||
|
IFNULL(ua.M_UserUsername,'') AS ApprovedByName
|
||||||
|
FROM purchase_request pr
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = pr.PurchaseRequestM_BranchCode
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = pr.PurchaseRequestS_RegionalID
|
||||||
|
LEFT JOIN item_category ic ON ic.itemCategoryID = pr.PurchaseRequestItemCategoryID
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = pr.PurchaseRequestCreatedUserID
|
||||||
|
LEFT JOIN m_user ua ON ua.M_UserID = pr.PurchaseRequestApprovedBy
|
||||||
|
WHERE pr.PurchaseRequestID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Purchase Request tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
prd.*,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM purchase_request_detail prd
|
||||||
|
LEFT JOIN m_item item ON item.M_ItemID = prd.PurchaseRequestDetailM_ItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = prd.PurchaseRequestDetailItemUnitID
|
||||||
|
WHERE prd.PurchaseRequestDetailPurchaseRequestID = ?
|
||||||
|
AND prd.PurchaseRequestDetailIsActive = 'Y'
|
||||||
|
ORDER BY prd.PurchaseRequestDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'STOCK REQUEST REPORT (PR)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['PurchaseRequestNumber'], true),
|
||||||
|
array('Ref Nomor', $header['PurchaseRequestRefNumber'] ?: '-', false),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDate']), false),
|
||||||
|
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestApprovedDate'])),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if (isset($item[2]) && $item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['PurchaseRequestNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['PurchaseRequestNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang', $header['M_BranchName']),
|
||||||
|
array('Regional', $header['S_RegionalName']),
|
||||||
|
array('Kategori', $header['itemCategoryName'] ?: '-'),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName']),
|
||||||
|
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 82 + 20 + 20 + 25 + 25 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama / Item', 82, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 20, 'R'),
|
||||||
|
array('Harga', 25, 'R'),
|
||||||
|
array('Total', 25, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_est = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['PurchaseRequestDetailQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['PurchaseRequestDetailPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['PurchaseRequestDetailTotal']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_est += floatval($d['PurchaseRequestDetailTotal']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($total_est), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Pengajuan pembelian ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses pembelian dilakukan.',
|
||||||
|
'Barang/jasa yang dibeli harus sesuai dengan spesifikasi dan kebutuhan yang tercantum dalam dokumen ini.',
|
||||||
|
'Pembayaran dilakukan setelah barang/jasa diterima dan diverifikasi sesuai pesanan.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses pengadaan.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
377
application/controllers/report/Rpt_stock_request_np.php
Normal file
377
application/controllers/report/Rpt_stock_request_np.php
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal.
|
||||||
|
// =============================================================================
|
||||||
|
class StockReqNpFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_stock_request_np extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var StockReqNpFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Stock Request Non Persediaan (PR-NP) Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (PurchaseRequestID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
|
||||||
|
// Validasi: Pastikan Kategori Item BUKAN '1' (Bukan Persediaan / Inventory)
|
||||||
|
if ($header['PurchaseRequestItemCategoryID'] == '1') {
|
||||||
|
$this->sys_error("Dokumen ini adalah kategori Persediaan. Gunakan report Stock Request biasa.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new StockReqNpFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'SR_NP_' . str_replace('/', '-', $header['PurchaseRequestNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
pr.*,
|
||||||
|
b.M_BranchName,
|
||||||
|
b.M_BranchAddress,
|
||||||
|
r.S_RegionalName,
|
||||||
|
ic.itemCategoryName,
|
||||||
|
IFNULL(u.M_UserUsername,'') AS CreatedByName,
|
||||||
|
IFNULL(ua.M_UserUsername,'') AS ApprovedByName
|
||||||
|
FROM purchase_request pr
|
||||||
|
LEFT JOIN m_branch b ON b.M_BranchCode = pr.PurchaseRequestM_BranchCode
|
||||||
|
LEFT JOIN s_regional r ON r.S_RegionalID = pr.PurchaseRequestS_RegionalID
|
||||||
|
LEFT JOIN item_category ic ON ic.itemCategoryID = pr.PurchaseRequestItemCategoryID
|
||||||
|
LEFT JOIN m_user u ON u.M_UserID = pr.PurchaseRequestCreatedUserID
|
||||||
|
LEFT JOIN m_user ua ON ua.M_UserID = pr.PurchaseRequestApprovedBy
|
||||||
|
WHERE pr.PurchaseRequestID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Purchase Request tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
prd.*,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode
|
||||||
|
FROM purchase_request_detail prd
|
||||||
|
LEFT JOIN m_item item ON item.M_ItemID = prd.PurchaseRequestDetailM_ItemID
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = prd.PurchaseRequestDetailItemUnitID
|
||||||
|
WHERE prd.PurchaseRequestDetailPurchaseRequestID = ?
|
||||||
|
AND prd.PurchaseRequestDetailIsActive = 'Y'
|
||||||
|
ORDER BY prd.PurchaseRequestDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'STOCK REQUEST REPORT (PR) - NON PERSEDIAAN', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['PurchaseRequestNumber'], true),
|
||||||
|
array('Ref Nomor', $header['PurchaseRequestRefNumber'] ?: '-', false),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['PurchaseRequestDate']), false),
|
||||||
|
array('Tanggal Approved', $this->_fmt_datetime($header['PurchaseRequestApprovedDate'])),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if (isset($item[2]) && $item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['PurchaseRequestNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['PurchaseRequestNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Cabang', $header['M_BranchName']),
|
||||||
|
array('Regional', $header['S_RegionalName']),
|
||||||
|
array('Kategori', $header['itemCategoryName'] ?: '-'),
|
||||||
|
array('Dibuat Oleh', $header['CreatedByName']),
|
||||||
|
array('Disetujui Oleh', $header['ApprovedByName'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item + ringkasan nilai
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 82 + 20 + 20 + 25 + 25 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama / Item', 82, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty', 20, 'R'),
|
||||||
|
array('Harga', 25, 'R'),
|
||||||
|
array('Total', 25, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
$total_est = 0;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['PurchaseRequestDetailQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_rp($d['PurchaseRequestDetailPrice']), 1, 0, 'R');
|
||||||
|
$pdf->Cell($cols[5][1], 6, $this->_fmt_rp($d['PurchaseRequestDetailTotal']), 1, 0, 'R');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$total_est += floatval($d['PurchaseRequestDetailTotal']);
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baris TOTAL
|
||||||
|
$span = array_sum(array_column(array_slice($cols, 0, 5), 1));
|
||||||
|
$pdf->SetLineWidth(0.3);
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9); // bold + size 9 agar menonjol
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->Cell($span, 7, 'TOTAL', 1, 0, 'R', true);
|
||||||
|
$pdf->Cell($cols[5][1], 7, $this->_fmt_rp($total_est), 1, 0, 'R', true);
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Pengajuan pembelian ini harus mendapatkan persetujuan dari pejabat berwenang sebelum proses pembelian dilakukan.',
|
||||||
|
'Barang/jasa yang dibeli harus sesuai dengan spesifikasi dan kebutuhan yang tercantum dalam dokumen ini.',
|
||||||
|
'Pembayaran dilakukan setelah barang/jasa diterima dan diverifikasi sesuai pesanan.',
|
||||||
|
'Dokumen ini bersifat internal dan hanya digunakan untuk keperluan proses pengadaan.',
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
379
application/controllers/report/Rpt_surat_jalan.php
Normal file
379
application/controllers/report/Rpt_surat_jalan.php
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
require_once(APPPATH . 'libraries/fpdf/fpdf.php');
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Custom FPDF: override Footer() agar tampil otomatis di SETIAP halaman
|
||||||
|
// Footer tidak bisa bergeser karena FPDF memanggil Footer() sebelum ganti hal.
|
||||||
|
// =============================================================================
|
||||||
|
class SuratJalanFpdf extends FPDF
|
||||||
|
{
|
||||||
|
public $printUsername = '-';
|
||||||
|
public $printDate = '';
|
||||||
|
|
||||||
|
public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
|
||||||
|
{
|
||||||
|
parent::__construct($orientation, $unit, $size);
|
||||||
|
// Daftarkan Arial Narrow — file font ada di fpdf/font/Arial_Narrow.php
|
||||||
|
$this->AddFont('Arial_Narrow', '', 'Arial_Narrow.php'); // regular
|
||||||
|
$this->AddFont('Arial_Narrow', 'B', 'Arial_Narrow_B.php'); // bold (Liberation Sans Narrow Bold)
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Footer()
|
||||||
|
{
|
||||||
|
$pageW = $this->GetPageWidth() - 30; // sama dengan margin 15+15
|
||||||
|
|
||||||
|
// ── Posisi: 20mm dari bawah halaman ──────────────────────────────────
|
||||||
|
$this->SetY(-20);
|
||||||
|
|
||||||
|
// ── Baris 1: Print Oleh (kiri) | Nomor Halaman (tengah) ───────────────
|
||||||
|
$colSide = ($pageW - 40) / 2;
|
||||||
|
$colCenter = 40;
|
||||||
|
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Print Oleh : ' . $this->printUsername, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter, 4, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||||
|
$this->Cell($colSide, 4, '', 0, 1, 'R');
|
||||||
|
|
||||||
|
// ── Baris 2: Tgl Print (kiri) ──────────────────────────────────────────
|
||||||
|
$this->SetFont('Arial_Narrow', '', 7);
|
||||||
|
$this->Cell($colSide, 4, 'Tgl Print : ' . $this->printDate, 0, 0, 'L');
|
||||||
|
$this->Cell($colCenter + $colSide, 4, '', 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Controller
|
||||||
|
// =============================================================================
|
||||||
|
class Rpt_surat_jalan extends MY_Controller
|
||||||
|
{
|
||||||
|
// ── Properti bersama antar fungsi PDF ─────────────────────────────────────
|
||||||
|
/** @var SuratJalanFpdf */
|
||||||
|
private $_pdf;
|
||||||
|
private $_pageW;
|
||||||
|
private $_header_data;
|
||||||
|
private $_username;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
echo "Surat Jalan Report API";
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ENDPOINT: pdf
|
||||||
|
// GET/POST: id (SuratJalanID), username (opsional)
|
||||||
|
// =========================================================================
|
||||||
|
public function pdf()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$id = intval($this->input->get_post('id'));
|
||||||
|
$username = trim($this->input->get_post('username') ?? '');
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
$this->sys_error("ID tidak valid");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ambil data header & detail dari DB ────────────────────────────
|
||||||
|
$header = $this->_get_header($id);
|
||||||
|
$details = $this->_get_detail($id);
|
||||||
|
|
||||||
|
// ── Inisialisasi FPDF custom ──────────────────────────────────────
|
||||||
|
$this->_pdf = new SuratJalanFpdf('P', 'mm', 'A4');
|
||||||
|
$this->_pdf->printUsername = $username !== '' ? $username : '-';
|
||||||
|
$this->_pdf->printDate = date('d-m-Y H:i:s');
|
||||||
|
$this->_pageW = $this->_pdf->GetPageWidth() - 30;
|
||||||
|
$this->_header_data = $header;
|
||||||
|
$this->_username = $this->_pdf->printUsername;
|
||||||
|
|
||||||
|
$this->_pdf->AliasNbPages(); // aktifkan alias total halaman
|
||||||
|
$this->_pdf->SetMargins(15, 15, 15);
|
||||||
|
$this->_pdf->SetAutoPageBreak(true, 22); // 22mm ruang footer di bawah
|
||||||
|
$this->_pdf->AddPage();
|
||||||
|
|
||||||
|
// ── Susun isi halaman ─────────────────────────────────────────────
|
||||||
|
$this->_pdf_header();
|
||||||
|
$this->_pdf_data($details);
|
||||||
|
$this->_pdf_terms();
|
||||||
|
|
||||||
|
// ── Output ────────────────────────────────────────────────────────
|
||||||
|
$filename = 'SJ_' . str_replace('/', '-', $header['SuratJalanNumber']) . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
echo $this->_pdf->Output('S');
|
||||||
|
} catch (Exception $exc) {
|
||||||
|
$this->sys_error($exc->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data header
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_header($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
sj.*,
|
||||||
|
ex.ExpeditionName,
|
||||||
|
ex.ExpeditionIsInternal,
|
||||||
|
exs.ExpeditionStaffName,
|
||||||
|
exs.ExpeditionStaffMobile,
|
||||||
|
tg.T_GoodsTransferNum,
|
||||||
|
tg.T_GoodsTransferDate,
|
||||||
|
tg.T_GoodsTransferType,
|
||||||
|
tg.T_GoodsTransferFromM_BranchCode,
|
||||||
|
tg.T_GoodsTransferToM_BranchCode,
|
||||||
|
rFrom.S_RegionalName AS RegionalFromName,
|
||||||
|
bTo.M_BranchName AS BranchToName,
|
||||||
|
bTo.M_BranchAddress AS BranchToAddress
|
||||||
|
FROM suratjalan sj
|
||||||
|
LEFT JOIN t_goods_transfer tg ON tg.T_GoodsTransferID = sj.SuratJalanT_GoodsTransferID
|
||||||
|
AND tg.T_GoodsTransferIsActive = 'Y'
|
||||||
|
LEFT JOIN expedition ex ON ex.ExpeditionID = sj.SuratJalanEkspedisiID
|
||||||
|
AND ex.ExpeditionIsActive = 'Y'
|
||||||
|
LEFT JOIN expeditionstaff exs ON exs.ExpeditionStaffID = sj.SuratJalanEkspedisiStaffID
|
||||||
|
AND exs.ExpeditionStaffIsActive = 'Y'
|
||||||
|
LEFT JOIN s_regional rFrom ON rFrom.S_RegionalID = tg.T_GoodsTransferFromS_RegionalID
|
||||||
|
LEFT JOIN m_branch bTo ON bTo.M_BranchCode = tg.T_GoodsTransferToM_BranchCode
|
||||||
|
WHERE sj.SuratJalanIsActive = 'Y'
|
||||||
|
AND sj.SuratJalanID = ?
|
||||||
|
LIMIT 1
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
if (!$qry || $qry->num_rows() === 0) {
|
||||||
|
$this->sys_error("Data Surat Jalan tidak ditemukan");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $qry->row_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// DATABASE: Ambil data detail
|
||||||
|
// =========================================================================
|
||||||
|
private function _get_detail($id)
|
||||||
|
{
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
sjd.*,
|
||||||
|
item.M_ItemCode,
|
||||||
|
item.M_ItemDesc,
|
||||||
|
iu.ItemUnitName,
|
||||||
|
iu.ItemUnitCode,
|
||||||
|
pr.PurchaseRequestNumber
|
||||||
|
FROM suratjalan_detail sjd
|
||||||
|
JOIN m_item item ON item.M_ItemID = sjd.SuratJalanDetailM_ItemID
|
||||||
|
AND item.M_ItemIsActive = 'Y'
|
||||||
|
LEFT JOIN itemunit iu ON iu.ItemUnitID = sjd.SuratJalanDetailItemUnitID
|
||||||
|
AND iu.ItemUnitIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_request_flag prf ON prf.PurchaseRequestFlagID = sjd.SuratJalanDetailPurchaseRequestFlagID
|
||||||
|
AND prf.PurchaseRequestFlagIsActive = 'Y'
|
||||||
|
LEFT JOIN purchase_request_detail prd ON prd.PurchaseRequestDetailID = prf.PurchaseRequestFlagPurchaseRequestDetailID
|
||||||
|
LEFT JOIN purchase_request pr ON pr.PurchaseRequestID = prd.PurchaseRequestDetailPurchaseRequestID
|
||||||
|
WHERE sjd.SuratJalanDetailIsActive = 'Y'
|
||||||
|
AND sjd.SuratJalanDetailSuratJalanID = ?
|
||||||
|
ORDER BY sjd.SuratJalanDetailID ASC
|
||||||
|
";
|
||||||
|
$qry = $this->db->query($sql, array($id));
|
||||||
|
return $qry ? $qry->result_array() : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Header — Judul + Informasi Dokumen (2 kolom)
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_header()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Judul utama ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 14);
|
||||||
|
$pdf->Cell($pageW, 8, 'SURAT JALAN (DELIVERY ORDER)', 0, 1, 'L');
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
$pdf->SetLineWidth(0.5);
|
||||||
|
$pdf->Line(15, $pdf->GetY(), 15 + $pageW, $pdf->GetY());
|
||||||
|
$pdf->Ln(2);
|
||||||
|
|
||||||
|
$startY = $pdf->GetY();
|
||||||
|
$halfW = $pageW / 2;
|
||||||
|
$lblW = 28;
|
||||||
|
$valW = $halfW - $lblW - 4;
|
||||||
|
|
||||||
|
// ── Kolom Kiri ────────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
|
||||||
|
$leftItems = array(
|
||||||
|
array('Nomor', $header['SuratJalanNumber'], true),
|
||||||
|
array('Tanggal', $this->_fmt_date($header['SuratJalanDate']), false),
|
||||||
|
array('No. Transfer', $header['SuratJalanT_GoodsTransferNum'] ?: '-', false),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($leftItems as $item) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
if ($item[2]) {
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
} else {
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
}
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keterangan / Note langsung di bawah Status (tanpa spasi vertikal)
|
||||||
|
if (!empty($header['SuratJalanNote'])) {
|
||||||
|
$pdf->SetX(15);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, 'Keterangan', 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->MultiCell($valW, 5, $header['SuratJalanNote'], 0, 'L');
|
||||||
|
}
|
||||||
|
$leftY = $pdf->GetY();
|
||||||
|
|
||||||
|
// ── Kolom Kanan ───────────────────────────────────────────────────────
|
||||||
|
$pdf->SetY($startY);
|
||||||
|
$rightX = 15 + $halfW;
|
||||||
|
|
||||||
|
$rightItems = array(
|
||||||
|
array('Dari Regional', $header['RegionalFromName'] ?: '-'),
|
||||||
|
array('Tujuan Cabang', $header['BranchToName'] ?: '-'),
|
||||||
|
array('Alamat Tujuan', $header['BranchToAddress'] ?: '-'),
|
||||||
|
array('Ekspedisi', $header['ExpeditionName'] ?: '-'),
|
||||||
|
array('Driver / Staf', $header['ExpeditionStaffName'] ?: '-'),
|
||||||
|
array('Kontak Driver', $header['SuratJalanEkspedisiStaffContact'] ?: '-'),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rightItems as $item) {
|
||||||
|
$pdf->SetX($rightX);
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
$pdf->Cell($lblW, 5, $item[0], 0, 0, 'L');
|
||||||
|
$pdf->Cell(4, 5, ':', 0, 0, 'C');
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 9);
|
||||||
|
|
||||||
|
if ($item[0] === 'Alamat Tujuan') {
|
||||||
|
$pdf->MultiCell($valW, 5, $item[1], 0, 'L');
|
||||||
|
} else {
|
||||||
|
$pdf->Cell($valW, 5, $item[1], 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$rightY = $pdf->GetY();
|
||||||
|
|
||||||
|
// Posisikan Y ke yang paling bawah + margin
|
||||||
|
$pdf->SetY(max($leftY, $rightY) + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Data — Tabel detail item
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_data($details)
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
$header = $this->_header_data;
|
||||||
|
|
||||||
|
// ── Definisi kolom: [label, lebar, align] ─────────────────────────────
|
||||||
|
// Total lebar = 180mm (A4 portrait: 210 - margin 15 kiri - 15 kanan)
|
||||||
|
// 8 + 104 + 20 + 20 + 28 = 180
|
||||||
|
$cols = array(
|
||||||
|
array('No', 8, 'C'),
|
||||||
|
array('Nama', 104, 'L'),
|
||||||
|
array('Unit', 20, 'C'),
|
||||||
|
array('Qty Kirim', 20, 'R'),
|
||||||
|
array('Qty Diterima', 28, 'R'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Header kolom
|
||||||
|
$pdf->SetLineWidth(0.3); // border medium
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 8);
|
||||||
|
$pdf->SetFillColor(220, 220, 220);
|
||||||
|
$pdf->SetDrawColor(0, 0, 0);
|
||||||
|
foreach ($cols as $c) {
|
||||||
|
$pdf->Cell($c[1], 7, $c[0], 1, 0, 'C', true);
|
||||||
|
}
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
// Baris data
|
||||||
|
$pdf->SetLineWidth(0.2); // border lebih tipis di data
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
$pdf->SetFillColor(255, 255, 255);
|
||||||
|
$no = 1;
|
||||||
|
|
||||||
|
foreach ($details as $d) {
|
||||||
|
$pdf->Cell($cols[0][1], 6, $no, 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[1][1], 6, $d['M_ItemDesc'] ?: ($d['M_ItemCode'] ?: '-'), 1, 0, 'L');
|
||||||
|
$pdf->Cell($cols[2][1], 6, $d['ItemUnitName'] ?: ($d['ItemUnitCode'] ?: '-'), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[3][1], 6, $this->_fmt_qty($d['SuratJalanDetailQty']), 1, 0, 'C');
|
||||||
|
$pdf->Cell($cols[4][1], 6, $this->_fmt_qty($d['SuratJalanDetailQtyReceived']), 1, 0, 'C');
|
||||||
|
$pdf->Ln();
|
||||||
|
|
||||||
|
$no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->Ln(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// PDF SECTION: Syarat & Ketentuan
|
||||||
|
// =========================================================================
|
||||||
|
private function _pdf_terms()
|
||||||
|
{
|
||||||
|
$pdf = $this->_pdf;
|
||||||
|
$pageW = $this->_pageW;
|
||||||
|
|
||||||
|
$terms = array(
|
||||||
|
'Barang yang dikirimkan harus diperiksa kesesuaiannya dengan fisik sebelum ditandatangani oleh penerima.',
|
||||||
|
'Segala klaim kerusakan atau kekurangan barang setelah serah terima menjadi tanggung jawab penerima barang.',
|
||||||
|
'Surat jalan ini harus dikembalikan ke bagian logistik pengirim setelah ditandatangani oleh penerima.',
|
||||||
|
'Dokumen ini merupakan bukti sah serah terima barang antar cabang.'
|
||||||
|
);
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', 'B', 9);
|
||||||
|
$pdf->Cell($pageW, 5, 'Syarat & Ketentuan:', 0, 1, 'L');
|
||||||
|
|
||||||
|
$pdf->SetFont('Arial_Narrow', '', 8);
|
||||||
|
foreach ($terms as $i => $t) {
|
||||||
|
$pdf->Cell(6, 5, ($i + 1) . '.', 0, 0, 'R');
|
||||||
|
$pdf->Cell($pageW - 6, 5, $t, 0, 1, 'L');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER: Format tampilan
|
||||||
|
// =========================================================================
|
||||||
|
private function _fmt_date($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '-';
|
||||||
|
return date('d-m-Y', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_datetime($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '-';
|
||||||
|
return date('d-m-Y H:i', strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_num($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// format jumlah/qty: tanpa desimal
|
||||||
|
private function _fmt_qty($n)
|
||||||
|
{
|
||||||
|
return number_format(floatval($n), 0, ',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _fmt_rp($n)
|
||||||
|
{
|
||||||
|
return 'Rp ' . number_format(floatval($n), 2, ',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
272
application/libraries/fpdf/FAQ.htm
Normal file
272
application/libraries/fpdf/FAQ.htm
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>FAQ</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="fpdf.css">
|
||||||
|
<style type="text/css">
|
||||||
|
ul {list-style-type:none; margin:0; padding:0}
|
||||||
|
ul#answers li {margin-top:1.8em}
|
||||||
|
.question {font-weight:bold; color:#900000}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>FAQ</h1>
|
||||||
|
<ul>
|
||||||
|
<li><b>1.</b> <a href='#q1'>What's exactly the license of FPDF? Are there any usage restrictions?</a></li>
|
||||||
|
<li><b>2.</b> <a href='#q2'>I get the following error when I try to generate a PDF: Some data has already been output, can't send PDF file</a></li>
|
||||||
|
<li><b>3.</b> <a href='#q3'>Accented letters are replaced with some strange characters like é.</a></li>
|
||||||
|
<li><b>4.</b> <a href='#q4'>I try to display the Euro symbol but it doesn't work.</a></li>
|
||||||
|
<li><b>5.</b> <a href='#q5'>I try to display a variable in the Header method but nothing prints.</a></li>
|
||||||
|
<li><b>6.</b> <a href='#q6'>I have defined the Header and Footer methods in my PDF class but nothing shows.</a></li>
|
||||||
|
<li><b>7.</b> <a href='#q7'>I can't make line breaks work. I put \n in the string printed by MultiCell but it doesn't work.</a></li>
|
||||||
|
<li><b>8.</b> <a href='#q8'>I use jQuery to generate the PDF but it doesn't show.</a></li>
|
||||||
|
<li><b>9.</b> <a href='#q9'>I draw a frame with very precise dimensions, but when printed I notice some differences.</a></li>
|
||||||
|
<li><b>10.</b> <a href='#q10'>I'd like to use the whole surface of the page, but when printed I always have some margins. How can I get rid of them?</a></li>
|
||||||
|
<li><b>11.</b> <a href='#q11'>How can I put a background in my PDF?</a></li>
|
||||||
|
<li><b>12.</b> <a href='#q12'>How can I set a specific header or footer on the first page?</a></li>
|
||||||
|
<li><b>13.</b> <a href='#q13'>I'd like to use extensions provided by different scripts. How can I combine them?</a></li>
|
||||||
|
<li><b>14.</b> <a href='#q14'>How can I open the PDF in a new tab?</a></li>
|
||||||
|
<li><b>15.</b> <a href='#q15'>How can I send the PDF by email?</a></li>
|
||||||
|
<li><b>16.</b> <a href='#q16'>What's the limit of the file sizes I can generate with FPDF?</a></li>
|
||||||
|
<li><b>17.</b> <a href='#q17'>Can I modify a PDF with FPDF?</a></li>
|
||||||
|
<li><b>18.</b> <a href='#q18'>I'd like to make a search engine in PHP and index PDF files. Can I do it with FPDF?</a></li>
|
||||||
|
<li><b>19.</b> <a href='#q19'>Can I convert an HTML page to PDF with FPDF?</a></li>
|
||||||
|
<li><b>20.</b> <a href='#q20'>Can I concatenate PDF files with FPDF?</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul id='answers'>
|
||||||
|
<li id='q1'>
|
||||||
|
<p><b>1.</b> <span class='question'>What's exactly the license of FPDF? Are there any usage restrictions?</span></p>
|
||||||
|
FPDF is released under a permissive license: there is no usage restriction. You may embed it
|
||||||
|
freely in your application (commercial or not), with or without modifications.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q2'>
|
||||||
|
<p><b>2.</b> <span class='question'>I get the following error when I try to generate a PDF: Some data has already been output, can't send PDF file</span></p>
|
||||||
|
You must send nothing to the browser except the PDF itself: no HTML, no space, no carriage return. A common
|
||||||
|
case is having extra blank at the end of an included script file.<br>
|
||||||
|
If you can't figure out where the problem comes from, this other message appearing just before can help you:<br>
|
||||||
|
<br>
|
||||||
|
<b>Warning:</b> Cannot modify header information - headers already sent by (output started at script.php:X)<br>
|
||||||
|
<br>
|
||||||
|
It means that script.php outputs something at line X. Go to this line and fix it.
|
||||||
|
In case the message doesn't show, first check that you didn't disable warnings, then add this at the very
|
||||||
|
beginning of your script:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>ob_end_clean();</code></pre>
|
||||||
|
</div>
|
||||||
|
If you still don't see it, disable zlib.output_compression in your php.ini and it should appear.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q3'>
|
||||||
|
<p><b>3.</b> <span class='question'>Accented letters are replaced with some strange characters like é.</span></p>
|
||||||
|
Don't use UTF-8 with the standard fonts; they expect text encoded in ISO-8859-1 or windows-1252.
|
||||||
|
You can use utf8_decode() to perform a conversion to ISO-8859-1:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>$str = utf8_decode($str);</code></pre>
|
||||||
|
</div>
|
||||||
|
But some characters such as Euro won't be translated correctly. If the iconv extension is available, the
|
||||||
|
right way to do it is the following:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>$str = iconv('UTF-8', 'windows-1252', $str);</code></pre>
|
||||||
|
</div>
|
||||||
|
In case you need characters outside windows-1252, take a look at tutorial #7 or
|
||||||
|
<a href="http://www.fpdf.org/?go=script&id=92" target="_blank">tFPDF</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q4'>
|
||||||
|
<p><b>4.</b> <span class='question'>I try to display the Euro symbol but it doesn't work.</span></p>
|
||||||
|
The standard fonts have the Euro character at position 128. You can define a constant like this
|
||||||
|
for convenience:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>define('EURO', chr(128));</code></pre>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q5'>
|
||||||
|
<p><b>5.</b> <span class='question'>I try to display a variable in the Header method but nothing prints.</span></p>
|
||||||
|
You have to use the <code>global</code> keyword to access global variables, for example:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>function Header()
|
||||||
|
{
|
||||||
|
global $title;
|
||||||
|
|
||||||
|
$this->SetFont('Arial', 'B', 15);
|
||||||
|
$this->Cell(0, 10, $title, 1, 1, 'C');
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = 'My title';</code></pre>
|
||||||
|
</div>
|
||||||
|
Alternatively, you can use an object property:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>function Header()
|
||||||
|
{
|
||||||
|
$this->SetFont('Arial', 'B', 15);
|
||||||
|
$this->Cell(0, 10, $this->title, 1, 1, 'C');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf->title = 'My title';</code></pre>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q6'>
|
||||||
|
<p><b>6.</b> <span class='question'>I have defined the Header and Footer methods in my PDF class but nothing shows.</span></p>
|
||||||
|
You have to create an object from the PDF class, not FPDF:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>$pdf = new PDF();</code></pre>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q7'>
|
||||||
|
<p><b>7.</b> <span class='question'>I can't make line breaks work. I put \n in the string printed by MultiCell but it doesn't work.</span></p>
|
||||||
|
You have to enclose your string with double quotes, not single ones.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q8'>
|
||||||
|
<p><b>8.</b> <span class='question'>I use jQuery to generate the PDF but it doesn't show.</span></p>
|
||||||
|
Don't use an AJAX request to retrieve the PDF.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q9'>
|
||||||
|
<p><b>9.</b> <span class='question'>I draw a frame with very precise dimensions, but when printed I notice some differences.</span></p>
|
||||||
|
To respect dimensions, select "None" for the Page Scaling setting instead of "Shrink to Printable Area" in the print dialog box.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q10'>
|
||||||
|
<p><b>10.</b> <span class='question'>I'd like to use the whole surface of the page, but when printed I always have some margins. How can I get rid of them?</span></p>
|
||||||
|
Printers have physical margins (different depending on the models); it is therefore impossible to remove
|
||||||
|
them and print on the whole surface of the paper.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q11'>
|
||||||
|
<p><b>11.</b> <span class='question'>How can I put a background in my PDF?</span></p>
|
||||||
|
For a picture, call Image() in the Header() method, before any other output. To set a background color, use Rect().
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q12'>
|
||||||
|
<p><b>12.</b> <span class='question'>How can I set a specific header or footer on the first page?</span></p>
|
||||||
|
Just test the page number:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>function Header()
|
||||||
|
{
|
||||||
|
if($this->PageNo()==1)
|
||||||
|
{
|
||||||
|
//First page
|
||||||
|
...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Other pages
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q13'>
|
||||||
|
<p><b>13.</b> <span class='question'>I'd like to use extensions provided by different scripts. How can I combine them?</span></p>
|
||||||
|
Use an inheritance chain. If you have two classes, say A in a.php:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>require('fpdf.php');
|
||||||
|
|
||||||
|
class A extends FPDF
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
and B in b.php:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>require('fpdf.php');
|
||||||
|
|
||||||
|
class B extends FPDF
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
then make B extend A:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>require('a.php');
|
||||||
|
|
||||||
|
class B extends A
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
and make your own class extend B:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>require('b.php');
|
||||||
|
|
||||||
|
class PDF extends B
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf = new PDF();</code></pre>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q14'>
|
||||||
|
<p><b>14.</b> <span class='question'>How can I open the PDF in a new tab?</span></p>
|
||||||
|
Just do the same as you would for an HTML page or anything else: add a target="_blank" to your link or form.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q15'>
|
||||||
|
<p><b>15.</b> <span class='question'>How can I send the PDF by email?</span></p>
|
||||||
|
As for any other file, but an easy way is to use <a href="https://github.com/PHPMailer/PHPMailer" target="_blank">PHPMailer</a> and
|
||||||
|
its in-memory attachment:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>$mail = new PHPMailer();
|
||||||
|
...
|
||||||
|
$doc = $pdf->Output('S');
|
||||||
|
$mail->AddStringAttachment($doc, 'doc.pdf', 'base64', 'application/pdf');
|
||||||
|
$mail->Send();</code></pre>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q16'>
|
||||||
|
<p><b>16.</b> <span class='question'>What's the limit of the file sizes I can generate with FPDF?</span></p>
|
||||||
|
There is no particular limit. There are some constraints, however:
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
- There is usually a maximum memory size allocated to PHP scripts. For very big documents,
|
||||||
|
especially with images, the limit may be reached (the file being built in memory). The
|
||||||
|
parameter is configured in the php.ini file.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
- The maximum execution time allocated to scripts defaults to 30 seconds. This limit can of course
|
||||||
|
be easily reached. It is configured in php.ini and may be altered dynamically with set_time_limit().
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
You can work around the memory limit with <a href="http://www.fpdf.org/?go=script&id=76" target="_blank">this script</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q17'>
|
||||||
|
<p><b>17.</b> <span class='question'>Can I modify a PDF with FPDF?</span></p>
|
||||||
|
It's possible to import pages from an existing PDF document thanks to the
|
||||||
|
<a href="https://www.setasign.com/products/fpdi/about/" target="_blank">FPDI</a> extension.
|
||||||
|
Then you can add some content to them.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q18'>
|
||||||
|
<p><b>18.</b> <span class='question'>I'd like to make a search engine in PHP and index PDF files. Can I do it with FPDF?</span></p>
|
||||||
|
No. But a GPL C utility does exist, pdftotext, which is able to extract the textual content from a PDF.
|
||||||
|
It's provided with the <a href="https://www.xpdfreader.com" target="_blank">Xpdf</a> package.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q19'>
|
||||||
|
<p><b>19.</b> <span class='question'>Can I convert an HTML page to PDF with FPDF?</span></p>
|
||||||
|
Not real-world pages. But a GPL C utility does exist, <a href="https://www.msweet.org/htmldoc/" target="_blank">HTMLDOC</a>,
|
||||||
|
which allows to do it and gives good results.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li id='q20'>
|
||||||
|
<p><b>20.</b> <span class='question'>Can I concatenate PDF files with FPDF?</span></p>
|
||||||
|
Not directly, but it's possible to use <a href="https://www.setasign.com/products/fpdi/demos/concatenate-fake/" target="_blank">FPDI</a>
|
||||||
|
to perform that task. Some free command-line tools also exist:
|
||||||
|
<a href="https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/" target="_blank">pdftk</a> and
|
||||||
|
<a href="http://thierry.schmit.free.fr/spip/spip.php?article15" target="_blank">mbtPdfAsm</a>.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
167
application/libraries/fpdf/changelog.htm
Normal file
167
application/libraries/fpdf/changelog.htm
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Changelog</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="fpdf.css">
|
||||||
|
<style type="text/css">
|
||||||
|
dd {margin:1em 0 1em 1em}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Changelog</h1>
|
||||||
|
<dl>
|
||||||
|
<dt><strong>v1.82</strong> (2019-12-07)</dt>
|
||||||
|
<dd>
|
||||||
|
- Removed a deprecation notice under PHP 7.4.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.81</strong> (2015-12-20)</dt>
|
||||||
|
<dd>
|
||||||
|
- Added GetPageWidth() and GetPageHeight().<br>
|
||||||
|
- Fixed a bug in SetXY().<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.8</strong> (2015-11-29)</dt>
|
||||||
|
<dd>
|
||||||
|
- PHP 5.1.0 or higher is now required.<br>
|
||||||
|
- The MakeFont utility now subsets fonts, which can greatly reduce font sizes.<br>
|
||||||
|
- Added ToUnicode CMaps to improve text extraction.<br>
|
||||||
|
- Added a parameter to AddPage() to rotate the page.<br>
|
||||||
|
- Added a parameter to SetY() to indicate whether the x position should be reset or not.<br>
|
||||||
|
- Added a parameter to Output() to specify the encoding of the name, and special characters are now properly encoded. Additionally the order of the first two parameters was reversed to be more logical (however the old order is still supported for compatibility).<br>
|
||||||
|
- The Error() method now throws an exception.<br>
|
||||||
|
- Adding contents before the first AddPage() or after Close() now raises an error.<br>
|
||||||
|
- Outputting text with no font selected now raises an error.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.7</strong> (2011-06-18)</dt>
|
||||||
|
<dd>
|
||||||
|
- The MakeFont utility has been completely rewritten and doesn't depend on ttf2pt1 anymore.<br>
|
||||||
|
- Alpha channel is now supported for PNGs.<br>
|
||||||
|
- When inserting an image, it's now possible to specify its resolution.<br>
|
||||||
|
- Default resolution for images was increased from 72 to 96 dpi.<br>
|
||||||
|
- When inserting a GIF image, no temporary file is used anymore if the PHP version is 5.1 or higher.<br>
|
||||||
|
- When output buffering is enabled and the PDF is about to be sent, the buffer is now cleared if it contains only a UTF-8 BOM and/or whitespace (instead of throwing an error).<br>
|
||||||
|
- Symbol and ZapfDingbats fonts now support underline style.<br>
|
||||||
|
- Custom page sizes are now checked to ensure that width is smaller than height.<br>
|
||||||
|
- Standard font files were changed to use the same format as user fonts.<br>
|
||||||
|
- A bug in the embedding of Type1 fonts was fixed.<br>
|
||||||
|
- A bug related to SetDisplayMode() and the current locale was fixed.<br>
|
||||||
|
- A display issue occurring with the Adobe Reader X plug-in was fixed.<br>
|
||||||
|
- An issue related to transparency with some versions of Adobe Reader was fixed.<br>
|
||||||
|
- The Content-Length header was removed because it caused an issue when the HTTP server applies compression.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.6</strong> (2008-08-03)</dt>
|
||||||
|
<dd>
|
||||||
|
- PHP 4.3.10 or higher is now required.<br>
|
||||||
|
- GIF image support.<br>
|
||||||
|
- Images can now trigger page breaks.<br>
|
||||||
|
- Possibility to have different page formats in a single document.<br>
|
||||||
|
- Document properties (author, creator, keywords, subject and title) can now be specified in UTF-8.<br>
|
||||||
|
- Fixed a bug: when a PNG was inserted through a URL, an error sometimes occurred.<br>
|
||||||
|
- An automatic page break in Header() doesn't cause an infinite loop any more.<br>
|
||||||
|
- Removed some warning messages appearing with recent PHP versions.<br>
|
||||||
|
- Added HTTP headers to reduce problems with IE.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.53</strong> (2004-12-31)</dt>
|
||||||
|
<dd>
|
||||||
|
- When the font subdirectory is in the same directory as fpdf.php, it's no longer necessary to define the FPDF_FONTPATH constant.<br>
|
||||||
|
- The array $HTTP_SERVER_VARS is no longer used. It could cause trouble on PHP5-based configurations with the register_long_arrays option disabled.<br>
|
||||||
|
- Fixed a problem related to Type1 font embedding which caused trouble to some PDF processors.<br>
|
||||||
|
- The file name sent to the browser could not contain a space character.<br>
|
||||||
|
- The Cell() method could not print the number 0 (you had to pass the string '0').<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.52</strong> (2003-12-30)</dt>
|
||||||
|
<dd>
|
||||||
|
- Image() now displays the image at 72 dpi if no dimension is given.<br>
|
||||||
|
- Output() takes a string as second parameter to indicate destination.<br>
|
||||||
|
- Open() is now called automatically by AddPage().<br>
|
||||||
|
- Inserting remote JPEG images doesn't generate an error any longer.<br>
|
||||||
|
- Decimal separator is forced to dot in the constructor.<br>
|
||||||
|
- Added several encodings (Turkish, Thai, Hebrew, Ukrainian and Vietnamese).<br>
|
||||||
|
- The last line of a right-aligned MultiCell() was not correctly aligned if it was terminated by a carriage return.<br>
|
||||||
|
- No more error message about already sent headers when outputting the PDF to the standard output from the command line.<br>
|
||||||
|
- The underlining was going too far for text containing characters \, ( or ).<br>
|
||||||
|
- $HTTP_ENV_VARS has been replaced by $HTTP_SERVER_VARS.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.51</strong> (2002-08-03)</dt>
|
||||||
|
<dd>
|
||||||
|
- Type1 font support.<br>
|
||||||
|
- Added Baltic encoding.<br>
|
||||||
|
- The class now works internally in points with the origin at the bottom in order to avoid two bugs occurring with Acrobat 5:<br> * The line thickness was too large when printed under Windows 98 SE and ME.<br> * TrueType fonts didn't appear immediately inside the plug-in (a substitution font was used), one had to cause a window refresh to make them show up.<br>
|
||||||
|
- It's no longer necessary to set the decimal separator as dot to produce valid documents.<br>
|
||||||
|
- The clickable area in a cell was always on the left independently from the text alignment.<br>
|
||||||
|
- JPEG images in CMYK mode appeared in inverted colors.<br>
|
||||||
|
- Transparent PNG images in grayscale or true color mode were incorrectly handled.<br>
|
||||||
|
- Adding new fonts now works correctly even with the magic_quotes_runtime option set to on.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.5</strong> (2002-05-28)</dt>
|
||||||
|
<dd>
|
||||||
|
- TrueType font (AddFont()) and encoding support (Western and Eastern Europe, Cyrillic and Greek).<br>
|
||||||
|
- Added Write() method.<br>
|
||||||
|
- Added underlined style.<br>
|
||||||
|
- Internal and external link support (AddLink(), SetLink(), Link()).<br>
|
||||||
|
- Added right margin management and methods SetRightMargin(), SetTopMargin().<br>
|
||||||
|
- Modification of SetDisplayMode() to select page layout.<br>
|
||||||
|
- The border parameter of MultiCell() now lets choose borders to draw as Cell().<br>
|
||||||
|
- When a document contains no page, Close() now calls AddPage() instead of causing a fatal error.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.41</strong> (2002-03-13)</dt>
|
||||||
|
<dd>
|
||||||
|
- Fixed SetDisplayMode() which no longer worked (the PDF viewer used its default display).<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.4</strong> (2002-03-02)</dt>
|
||||||
|
<dd>
|
||||||
|
- PHP3 is no longer supported.<br>
|
||||||
|
- Page compression (SetCompression()).<br>
|
||||||
|
- Choice of page format and possibility to change orientation inside document.<br>
|
||||||
|
- Added AcceptPageBreak() method.<br>
|
||||||
|
- Ability to print the total number of pages (AliasNbPages()).<br>
|
||||||
|
- Choice of cell borders to draw.<br>
|
||||||
|
- New mode for Cell(): the current position can now move under the cell.<br>
|
||||||
|
- Ability to include an image by specifying height only (width is calculated automatically).<br>
|
||||||
|
- Fixed a bug: when a justified line triggered a page break, the footer inherited the corresponding word spacing.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.31</strong> (2002-01-12)</dt>
|
||||||
|
<dd>
|
||||||
|
- Fixed a bug in drawing frame with MultiCell(): the last line always started from the left margin.<br>
|
||||||
|
- Removed Expires HTTP header (gives trouble in some situations).<br>
|
||||||
|
- Added Content-disposition HTTP header (seems to help in some situations).<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.3</strong> (2001-12-03)</dt>
|
||||||
|
<dd>
|
||||||
|
- Line break and text justification support (MultiCell()).<br>
|
||||||
|
- Color support (SetDrawColor(), SetFillColor(), SetTextColor()). Possibility to draw filled rectangles and paint cell background.<br>
|
||||||
|
- A cell whose width is declared null extends up to the right margin of the page.<br>
|
||||||
|
- Line width is now retained from page to page and defaults to 0.2 mm.<br>
|
||||||
|
- Added SetXY() method.<br>
|
||||||
|
- Fixed a passing by reference done in a deprecated manner for PHP4.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.2</strong> (2001-11-11)</dt>
|
||||||
|
<dd>
|
||||||
|
- Added font metric files and GetStringWidth() method.<br>
|
||||||
|
- Centering and right-aligning text in cells.<br>
|
||||||
|
- Display mode control (SetDisplayMode()).<br>
|
||||||
|
- Added methods to set document properties (SetAuthor(), SetCreator(), SetKeywords(), SetSubject(), SetTitle()).<br>
|
||||||
|
- Possibility to force PDF download by browser.<br>
|
||||||
|
- Added SetX() and GetX() methods.<br>
|
||||||
|
- During automatic page break, current abscissa is now retained.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.11</strong> (2001-10-20)</dt>
|
||||||
|
<dd>
|
||||||
|
- PNG support doesn't require PHP4/zlib any more. Data are now put directly into PDF without any decompression/recompression stage.<br>
|
||||||
|
- Image insertion now works correctly even with magic_quotes_runtime option set to on.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.1</strong> (2001-10-07)</dt>
|
||||||
|
<dd>
|
||||||
|
- JPEG and PNG image support.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.01</strong> (2001-10-03)</dt>
|
||||||
|
<dd>
|
||||||
|
- Fixed a bug involving page break: in case when Header() doesn't specify a font, the one from previous page was not restored and produced an incorrect document.<br>
|
||||||
|
</dd>
|
||||||
|
<dt><strong>v1.0</strong> (2001-09-17)</dt>
|
||||||
|
<dd>
|
||||||
|
- First version.<br>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
63
application/libraries/fpdf/doc/__construct.htm
Normal file
63
application/libraries/fpdf/doc/__construct.htm
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>__construct</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>__construct</h1>
|
||||||
|
<code>__construct([<b>string</b> orientation [, <b>string</b> unit [, <b>mixed</b> size]]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
This is the class constructor. It allows to set up the page size, the orientation and the
|
||||||
|
unit of measure used in all methods (except for font sizes).
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>orientation</code></dt>
|
||||||
|
<dd>
|
||||||
|
Default page orientation. Possible values are (case insensitive):
|
||||||
|
<ul>
|
||||||
|
<li><code>P</code> or <code>Portrait</code></li>
|
||||||
|
<li><code>L</code> or <code>Landscape</code></li>
|
||||||
|
</ul>
|
||||||
|
Default value is <code>P</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>unit</code></dt>
|
||||||
|
<dd>
|
||||||
|
User unit. Possible values are:
|
||||||
|
<ul>
|
||||||
|
<li><code>pt</code>: point</li>
|
||||||
|
<li><code>mm</code>: millimeter</li>
|
||||||
|
<li><code>cm</code>: centimeter</li>
|
||||||
|
<li><code>in</code>: inch</li>
|
||||||
|
</ul>
|
||||||
|
A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This
|
||||||
|
is a very common unit in typography; font sizes are expressed in that unit.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Default value is <code>mm</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>size</code></dt>
|
||||||
|
<dd>
|
||||||
|
The size used for pages. It can be either one of the following values (case insensitive):
|
||||||
|
<ul>
|
||||||
|
<li><code>A3</code></li>
|
||||||
|
<li><code>A4</code></li>
|
||||||
|
<li><code>A5</code></li>
|
||||||
|
<li><code>Letter</code></li>
|
||||||
|
<li><code>Legal</code></li>
|
||||||
|
</ul>
|
||||||
|
or an array containing the width and the height (expressed in the unit given by <code>unit</code>).<br>
|
||||||
|
<br>
|
||||||
|
Default value is <code>A4</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Example</h2>
|
||||||
|
Example with a custom 100x150 mm page size:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>$pdf = new FPDF('P','mm',array(100,150));</code></pre>
|
||||||
|
</div>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
63
application/libraries/fpdf/doc/acceptpagebreak.htm
Normal file
63
application/libraries/fpdf/doc/acceptpagebreak.htm
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>AcceptPageBreak</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>AcceptPageBreak</h1>
|
||||||
|
<code><b>boolean</b> AcceptPageBreak()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Whenever a page break condition is met, the method is called, and the break is issued or not
|
||||||
|
depending on the returned value. The default implementation returns a value according to the
|
||||||
|
mode selected by SetAutoPageBreak().
|
||||||
|
<br>
|
||||||
|
This method is called automatically and should not be called directly by the application.
|
||||||
|
<h2>Example</h2>
|
||||||
|
The method is overriden in an inherited class in order to obtain a 3 column layout:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>class PDF extends FPDF
|
||||||
|
{
|
||||||
|
var $col = 0;
|
||||||
|
|
||||||
|
function SetCol($col)
|
||||||
|
{
|
||||||
|
// Move position to a column
|
||||||
|
$this->col = $col;
|
||||||
|
$x = 10+$col*65;
|
||||||
|
$this->SetLeftMargin($x);
|
||||||
|
$this->SetX($x);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AcceptPageBreak()
|
||||||
|
{
|
||||||
|
if($this->col<2)
|
||||||
|
{
|
||||||
|
// Go to next column
|
||||||
|
$this->SetCol($this->col+1);
|
||||||
|
$this->SetY(10);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Go back to first column and issue page break
|
||||||
|
$this->SetCol(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf = new PDF();
|
||||||
|
$pdf->AddPage();
|
||||||
|
$pdf->SetFont('Arial','',12);
|
||||||
|
for($i=1;$i<=300;$i++)
|
||||||
|
$pdf->Cell(0,5,"Line $i",0,1);
|
||||||
|
$pdf->Output();</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
55
application/libraries/fpdf/doc/addfont.htm
Normal file
55
application/libraries/fpdf/doc/addfont.htm
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>AddFont</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>AddFont</h1>
|
||||||
|
<code>AddFont(<b>string</b> family [, <b>string</b> style [, <b>string</b> file]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Imports a TrueType, OpenType or Type1 font and makes it available. It is necessary to generate a font
|
||||||
|
definition file first with the MakeFont utility.
|
||||||
|
<br>
|
||||||
|
The definition file (and the font file itself when embedding) must be present in the font directory.
|
||||||
|
If it is not found, the error "Could not include font definition file" is raised.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>family</code></dt>
|
||||||
|
<dd>
|
||||||
|
Font family. The name can be chosen arbitrarily. If it is a standard family name, it will
|
||||||
|
override the corresponding font.
|
||||||
|
</dd>
|
||||||
|
<dt><code>style</code></dt>
|
||||||
|
<dd>
|
||||||
|
Font style. Possible values are (case insensitive):
|
||||||
|
<ul>
|
||||||
|
<li>empty string: regular</li>
|
||||||
|
<li><code>B</code>: bold</li>
|
||||||
|
<li><code>I</code>: italic</li>
|
||||||
|
<li><code>BI</code> or <code>IB</code>: bold italic</li>
|
||||||
|
</ul>
|
||||||
|
The default value is regular.
|
||||||
|
</dd>
|
||||||
|
<dt><code>file</code></dt>
|
||||||
|
<dd>
|
||||||
|
The font definition file.
|
||||||
|
<br>
|
||||||
|
By default, the name is built from the family and style, in lower case with no space.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>$pdf->AddFont('Comic','I');</code></pre>
|
||||||
|
</div>
|
||||||
|
is equivalent to:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>$pdf->AddFont('Comic','I','comici.php');</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setfont.htm">SetFont</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
26
application/libraries/fpdf/doc/addlink.htm
Normal file
26
application/libraries/fpdf/doc/addlink.htm
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>AddLink</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>AddLink</h1>
|
||||||
|
<code><b>int</b> AddLink()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Creates a new internal link and returns its identifier. An internal link is a clickable area
|
||||||
|
which directs to another place within the document.
|
||||||
|
<br>
|
||||||
|
The identifier can then be passed to Cell(), Write(), Image() or Link(). The destination is
|
||||||
|
defined with SetLink().
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="write.htm">Write</a>,
|
||||||
|
<a href="image.htm">Image</a>,
|
||||||
|
<a href="link.htm">Link</a>,
|
||||||
|
<a href="setlink.htm">SetLink</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
61
application/libraries/fpdf/doc/addpage.htm
Normal file
61
application/libraries/fpdf/doc/addpage.htm
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>AddPage</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>AddPage</h1>
|
||||||
|
<code>AddPage([<b>string</b> orientation [, <b>mixed</b> size [, <b>int</b> rotation]]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Adds a new page to the document. If a page is already present, the Footer() method is called
|
||||||
|
first to output the footer. Then the page is added, the current position set to the top-left
|
||||||
|
corner according to the left and top margins, and Header() is called to display the header.
|
||||||
|
<br>
|
||||||
|
The font which was set before calling is automatically restored. There is no need to call
|
||||||
|
SetFont() again if you want to continue with the same font. The same is true for colors and
|
||||||
|
line width.
|
||||||
|
<br>
|
||||||
|
The origin of the coordinate system is at the top-left corner and increasing ordinates go
|
||||||
|
downwards.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>orientation</code></dt>
|
||||||
|
<dd>
|
||||||
|
Page orientation. Possible values are (case insensitive):
|
||||||
|
<ul>
|
||||||
|
<li><code>P</code> or <code>Portrait</code></li>
|
||||||
|
<li><code>L</code> or <code>Landscape</code></li>
|
||||||
|
</ul>
|
||||||
|
The default value is the one passed to the constructor.
|
||||||
|
</dd>
|
||||||
|
<dt><code>size</code></dt>
|
||||||
|
<dd>
|
||||||
|
Page size. It can be either one of the following values (case insensitive):
|
||||||
|
<ul>
|
||||||
|
<li><code>A3</code></li>
|
||||||
|
<li><code>A4</code></li>
|
||||||
|
<li><code>A5</code></li>
|
||||||
|
<li><code>Letter</code></li>
|
||||||
|
<li><code>Legal</code></li>
|
||||||
|
</ul>
|
||||||
|
or an array containing the width and the height (expressed in user unit).<br>
|
||||||
|
<br>
|
||||||
|
The default value is the one passed to the constructor.
|
||||||
|
</dd>
|
||||||
|
<dt><code>rotation</code></dt>
|
||||||
|
<dd>
|
||||||
|
Angle by which to rotate the page. It must be a multiple of 90; positive values
|
||||||
|
mean clockwise rotation. The default value is <code>0</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="__construct.htm">__construct</a>,
|
||||||
|
<a href="header.htm">Header</a>,
|
||||||
|
<a href="footer.htm">Footer</a>,
|
||||||
|
<a href="setmargins.htm">SetMargins</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
45
application/libraries/fpdf/doc/aliasnbpages.htm
Normal file
45
application/libraries/fpdf/doc/aliasnbpages.htm
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>AliasNbPages</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>AliasNbPages</h1>
|
||||||
|
<code>AliasNbPages([<b>string</b> alias])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines an alias for the total number of pages. It will be substituted as the document is
|
||||||
|
closed.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>alias</code></dt>
|
||||||
|
<dd>
|
||||||
|
The alias. Default value: <code>{nb}</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>class PDF extends FPDF
|
||||||
|
{
|
||||||
|
function Footer()
|
||||||
|
{
|
||||||
|
// Go to 1.5 cm from bottom
|
||||||
|
$this->SetY(-15);
|
||||||
|
// Select Arial italic 8
|
||||||
|
$this->SetFont('Arial','I',8);
|
||||||
|
// Print current and total page numbers
|
||||||
|
$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf = new PDF();
|
||||||
|
$pdf->AliasNbPages();</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="pageno.htm">PageNo</a>,
|
||||||
|
<a href="footer.htm">Footer</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
104
application/libraries/fpdf/doc/cell.htm
Normal file
104
application/libraries/fpdf/doc/cell.htm
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Cell</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Cell</h1>
|
||||||
|
<code>Cell(<b>float</b> w [, <b>float</b> h [, <b>string</b> txt [, <b>mixed</b> border [, <b>int</b> ln [, <b>string</b> align [, <b>boolean</b> fill [, <b>mixed</b> link]]]]]]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Prints a cell (rectangular area) with optional borders, background color and character string.
|
||||||
|
The upper-left corner of the cell corresponds to the current position. The text can be aligned
|
||||||
|
or centered. After the call, the current position moves to the right or to the next line. It is
|
||||||
|
possible to put a link on the text.
|
||||||
|
<br>
|
||||||
|
If automatic page breaking is enabled and the cell goes beyond the limit, a page break is
|
||||||
|
done before outputting.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>w</code></dt>
|
||||||
|
<dd>
|
||||||
|
Cell width. If <code>0</code>, the cell extends up to the right margin.
|
||||||
|
</dd>
|
||||||
|
<dt><code>h</code></dt>
|
||||||
|
<dd>
|
||||||
|
Cell height.
|
||||||
|
Default value: <code>0</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>txt</code></dt>
|
||||||
|
<dd>
|
||||||
|
String to print.
|
||||||
|
Default value: empty string.
|
||||||
|
</dd>
|
||||||
|
<dt><code>border</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if borders must be drawn around the cell. The value can be either a number:
|
||||||
|
<ul>
|
||||||
|
<li><code>0</code>: no border</li>
|
||||||
|
<li><code>1</code>: frame</li>
|
||||||
|
</ul>
|
||||||
|
or a string containing some or all of the following characters (in any order):
|
||||||
|
<ul>
|
||||||
|
<li><code>L</code>: left</li>
|
||||||
|
<li><code>T</code>: top</li>
|
||||||
|
<li><code>R</code>: right</li>
|
||||||
|
<li><code>B</code>: bottom</li>
|
||||||
|
</ul>
|
||||||
|
Default value: <code>0</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>ln</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates where the current position should go after the call. Possible values are:
|
||||||
|
<ul>
|
||||||
|
<li><code>0</code>: to the right</li>
|
||||||
|
<li><code>1</code>: to the beginning of the next line</li>
|
||||||
|
<li><code>2</code>: below</li>
|
||||||
|
</ul>
|
||||||
|
Putting <code>1</code> is equivalent to putting <code>0</code> and calling Ln() just after.
|
||||||
|
Default value: <code>0</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>align</code></dt>
|
||||||
|
<dd>
|
||||||
|
Allows to center or align the text. Possible values are:
|
||||||
|
<ul>
|
||||||
|
<li><code>L</code> or empty string: left align (default value)</li>
|
||||||
|
<li><code>C</code>: center</li>
|
||||||
|
<li><code>R</code>: right align</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
<dt><code>fill</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if the cell background must be painted (<code>true</code>) or transparent (<code>false</code>).
|
||||||
|
Default value: <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>link</code></dt>
|
||||||
|
<dd>
|
||||||
|
URL or identifier returned by AddLink().
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>// Set font
|
||||||
|
$pdf->SetFont('Arial','B',16);
|
||||||
|
// Move to 8 cm to the right
|
||||||
|
$pdf->Cell(80);
|
||||||
|
// Centered text in a framed 20*10 mm cell and line break
|
||||||
|
$pdf->Cell(20,10,'Title',1,1,'C');</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setfont.htm">SetFont</a>,
|
||||||
|
<a href="setdrawcolor.htm">SetDrawColor</a>,
|
||||||
|
<a href="setfillcolor.htm">SetFillColor</a>,
|
||||||
|
<a href="settextcolor.htm">SetTextColor</a>,
|
||||||
|
<a href="setlinewidth.htm">SetLineWidth</a>,
|
||||||
|
<a href="addlink.htm">AddLink</a>,
|
||||||
|
<a href="ln.htm">Ln</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>,
|
||||||
|
<a href="write.htm">Write</a>,
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
21
application/libraries/fpdf/doc/close.htm
Normal file
21
application/libraries/fpdf/doc/close.htm
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Close</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Close</h1>
|
||||||
|
<code>Close()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Terminates the PDF document. It is not necessary to call this method explicitly because Output()
|
||||||
|
does it automatically.
|
||||||
|
<br>
|
||||||
|
If the document contains no page, AddPage() is called to prevent from getting an invalid document.
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="output.htm">Output</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
26
application/libraries/fpdf/doc/error.htm
Normal file
26
application/libraries/fpdf/doc/error.htm
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Error</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Error</h1>
|
||||||
|
<code>Error(<b>string</b> msg)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
This method is automatically called in case of a fatal error; it simply throws an exception
|
||||||
|
with the provided message.<br>
|
||||||
|
An inherited class may override it to customize the error handling but the method should
|
||||||
|
never return, otherwise the resulting document would probably be invalid.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>msg</code></dt>
|
||||||
|
<dd>
|
||||||
|
The error message.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
35
application/libraries/fpdf/doc/footer.htm
Normal file
35
application/libraries/fpdf/doc/footer.htm
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Footer</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Footer</h1>
|
||||||
|
<code>Footer()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
This method is used to render the page footer. It is automatically called by AddPage() and
|
||||||
|
Close() and should not be called directly by the application. The implementation in FPDF is
|
||||||
|
empty, so you have to subclass it and override the method if you want a specific processing.
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>class PDF extends FPDF
|
||||||
|
{
|
||||||
|
function Footer()
|
||||||
|
{
|
||||||
|
// Go to 1.5 cm from bottom
|
||||||
|
$this->SetY(-15);
|
||||||
|
// Select Arial italic 8
|
||||||
|
$this->SetFont('Arial','I',8);
|
||||||
|
// Print centered page number
|
||||||
|
$this->Cell(0,10,'Page '.$this->PageNo(),0,0,'C');
|
||||||
|
}
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="header.htm">Header</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
application/libraries/fpdf/doc/getpageheight.htm
Normal file
18
application/libraries/fpdf/doc/getpageheight.htm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>GetPageHeight</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>GetPageHeight</h1>
|
||||||
|
<code><b>float</b> GetPageHeight()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Returns the current page height.
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="getpagewidth.htm">GetPageWidth</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
application/libraries/fpdf/doc/getpagewidth.htm
Normal file
18
application/libraries/fpdf/doc/getpagewidth.htm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>GetPageWidth</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>GetPageWidth</h1>
|
||||||
|
<code><b>float</b> GetPageWidth()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Returns the current page width.
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="getpageheight.htm">GetPageHeight</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
23
application/libraries/fpdf/doc/getstringwidth.htm
Normal file
23
application/libraries/fpdf/doc/getstringwidth.htm
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>GetStringWidth</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>GetStringWidth</h1>
|
||||||
|
<code><b>float</b> GetStringWidth(<b>string</b> s)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Returns the length of a string in user unit. A font must be selected.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>s</code></dt>
|
||||||
|
<dd>
|
||||||
|
The string whose length is to be computed.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
application/libraries/fpdf/doc/getx.htm
Normal file
20
application/libraries/fpdf/doc/getx.htm
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>GetX</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>GetX</h1>
|
||||||
|
<code><b>float</b> GetX()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Returns the abscissa of the current position.
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setx.htm">SetX</a>,
|
||||||
|
<a href="gety.htm">GetY</a>,
|
||||||
|
<a href="sety.htm">SetY</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
application/libraries/fpdf/doc/gety.htm
Normal file
20
application/libraries/fpdf/doc/gety.htm
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>GetY</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>GetY</h1>
|
||||||
|
<code><b>float</b> GetY()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Returns the ordinate of the current position.
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="sety.htm">SetY</a>,
|
||||||
|
<a href="getx.htm">GetX</a>,
|
||||||
|
<a href="setx.htm">SetX</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
37
application/libraries/fpdf/doc/header.htm
Normal file
37
application/libraries/fpdf/doc/header.htm
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Header</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Header</h1>
|
||||||
|
<code>Header()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
This method is used to render the page header. It is automatically called by AddPage() and
|
||||||
|
should not be called directly by the application. The implementation in FPDF is empty, so
|
||||||
|
you have to subclass it and override the method if you want a specific processing.
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>class PDF extends FPDF
|
||||||
|
{
|
||||||
|
function Header()
|
||||||
|
{
|
||||||
|
// Select Arial bold 15
|
||||||
|
$this->SetFont('Arial','B',15);
|
||||||
|
// Move to the right
|
||||||
|
$this->Cell(80);
|
||||||
|
// Framed title
|
||||||
|
$this->Cell(30,10,'Title',1,0,'C');
|
||||||
|
// Line break
|
||||||
|
$this->Ln(20);
|
||||||
|
}
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="footer.htm">Footer</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
99
application/libraries/fpdf/doc/image.htm
Normal file
99
application/libraries/fpdf/doc/image.htm
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Image</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Image</h1>
|
||||||
|
<code>Image(<b>string</b> file [, <b>float</b> x [, <b>float</b> y [, <b>float</b> w [, <b>float</b> h [, <b>string</b> type [, <b>mixed</b> link]]]]]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Puts an image. The size it will take on the page can be specified in different ways:
|
||||||
|
<ul>
|
||||||
|
<li>explicit width and height (expressed in user unit or dpi)</li>
|
||||||
|
<li>one explicit dimension, the other being calculated automatically in order to keep the original proportions</li>
|
||||||
|
<li>no explicit dimension, in which case the image is put at 96 dpi</li>
|
||||||
|
</ul>
|
||||||
|
Supported formats are JPEG, PNG and GIF. The GD extension is required for GIF.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
For JPEGs, all flavors are allowed:
|
||||||
|
<ul>
|
||||||
|
<li>gray scales</li>
|
||||||
|
<li>true colors (24 bits)</li>
|
||||||
|
<li>CMYK (32 bits)</li>
|
||||||
|
</ul>
|
||||||
|
For PNGs, are allowed:
|
||||||
|
<ul>
|
||||||
|
<li>gray scales on at most 8 bits (256 levels)</li>
|
||||||
|
<li>indexed colors</li>
|
||||||
|
<li>true colors (24 bits)</li>
|
||||||
|
</ul>
|
||||||
|
For GIFs: in case of an animated GIF, only the first frame is displayed.<br>
|
||||||
|
<br>
|
||||||
|
Transparency is supported.<br>
|
||||||
|
<br>
|
||||||
|
The format can be specified explicitly or inferred from the file extension.<br>
|
||||||
|
<br>
|
||||||
|
It is possible to put a link on the image.<br>
|
||||||
|
<br>
|
||||||
|
Remark: if an image is used several times, only one copy is embedded in the file.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>file</code></dt>
|
||||||
|
<dd>
|
||||||
|
Path or URL of the image.
|
||||||
|
</dd>
|
||||||
|
<dt><code>x</code></dt>
|
||||||
|
<dd>
|
||||||
|
Abscissa of the upper-left corner. If not specified or equal to <code>null</code>, the current abscissa
|
||||||
|
is used.
|
||||||
|
</dd>
|
||||||
|
<dt><code>y</code></dt>
|
||||||
|
<dd>
|
||||||
|
Ordinate of the upper-left corner. If not specified or equal to <code>null</code>, the current ordinate
|
||||||
|
is used; moreover, a page break is triggered first if necessary (in case automatic page breaking is enabled)
|
||||||
|
and, after the call, the current ordinate is moved to the bottom of the image.
|
||||||
|
</dd>
|
||||||
|
<dt><code>w</code></dt>
|
||||||
|
<dd>
|
||||||
|
Width of the image in the page. There are three cases:
|
||||||
|
<ul>
|
||||||
|
<li>If the value is positive, it represents the width in user unit</li>
|
||||||
|
<li>If the value is negative, the absolute value represents the horizontal resolution in dpi</li>
|
||||||
|
<li>If the value is not specified or equal to zero, it is automatically calculated</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
<dt><code>h</code></dt>
|
||||||
|
<dd>
|
||||||
|
Height of the image in the page. There are three cases:
|
||||||
|
<ul>
|
||||||
|
<li>If the value is positive, it represents the height in user unit</li>
|
||||||
|
<li>If the value is negative, the absolute value represents the vertical resolution in dpi</li>
|
||||||
|
<li>If the value is not specified or equal to zero, it is automatically calculated</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
<dt><code>type</code></dt>
|
||||||
|
<dd>
|
||||||
|
Image format. Possible values are (case insensitive): <code>JPG</code>, <code>JPEG</code>, <code>PNG</code> and <code>GIF</code>.
|
||||||
|
If not specified, the type is inferred from the file extension.
|
||||||
|
</dd>
|
||||||
|
<dt><code>link</code></dt>
|
||||||
|
<dd>
|
||||||
|
URL or identifier returned by AddLink().
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>// Insert a logo in the top-left corner at 300 dpi
|
||||||
|
$pdf->Image('logo.png',10,10,-300);
|
||||||
|
// Insert a dynamic image from a URL
|
||||||
|
$pdf->Image('http://chart.googleapis.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World',60,30,90,0,'PNG');</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="addlink.htm">AddLink</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
59
application/libraries/fpdf/doc/index.htm
Normal file
59
application/libraries/fpdf/doc/index.htm
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>FPDF 1.82 Reference Manual</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>FPDF 1.82 Reference Manual</h1>
|
||||||
|
<a href="__construct.htm">__construct</a> - constructor<br>
|
||||||
|
<a href="acceptpagebreak.htm">AcceptPageBreak</a> - accept or not automatic page break<br>
|
||||||
|
<a href="addfont.htm">AddFont</a> - add a new font<br>
|
||||||
|
<a href="addlink.htm">AddLink</a> - create an internal link<br>
|
||||||
|
<a href="addpage.htm">AddPage</a> - add a new page<br>
|
||||||
|
<a href="aliasnbpages.htm">AliasNbPages</a> - define an alias for number of pages<br>
|
||||||
|
<a href="cell.htm">Cell</a> - print a cell<br>
|
||||||
|
<a href="close.htm">Close</a> - terminate the document<br>
|
||||||
|
<a href="error.htm">Error</a> - fatal error<br>
|
||||||
|
<a href="footer.htm">Footer</a> - page footer<br>
|
||||||
|
<a href="getpageheight.htm">GetPageHeight</a> - get current page height<br>
|
||||||
|
<a href="getpagewidth.htm">GetPageWidth</a> - get current page width<br>
|
||||||
|
<a href="getstringwidth.htm">GetStringWidth</a> - compute string length<br>
|
||||||
|
<a href="getx.htm">GetX</a> - get current x position<br>
|
||||||
|
<a href="gety.htm">GetY</a> - get current y position<br>
|
||||||
|
<a href="header.htm">Header</a> - page header<br>
|
||||||
|
<a href="image.htm">Image</a> - output an image<br>
|
||||||
|
<a href="line.htm">Line</a> - draw a line<br>
|
||||||
|
<a href="link.htm">Link</a> - put a link<br>
|
||||||
|
<a href="ln.htm">Ln</a> - line break<br>
|
||||||
|
<a href="multicell.htm">MultiCell</a> - print text with line breaks<br>
|
||||||
|
<a href="output.htm">Output</a> - save or send the document<br>
|
||||||
|
<a href="pageno.htm">PageNo</a> - page number<br>
|
||||||
|
<a href="rect.htm">Rect</a> - draw a rectangle<br>
|
||||||
|
<a href="setauthor.htm">SetAuthor</a> - set the document author<br>
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a> - set the automatic page breaking mode<br>
|
||||||
|
<a href="setcompression.htm">SetCompression</a> - turn compression on or off<br>
|
||||||
|
<a href="setcreator.htm">SetCreator</a> - set document creator<br>
|
||||||
|
<a href="setdisplaymode.htm">SetDisplayMode</a> - set display mode<br>
|
||||||
|
<a href="setdrawcolor.htm">SetDrawColor</a> - set drawing color<br>
|
||||||
|
<a href="setfillcolor.htm">SetFillColor</a> - set filling color<br>
|
||||||
|
<a href="setfont.htm">SetFont</a> - set font<br>
|
||||||
|
<a href="setfontsize.htm">SetFontSize</a> - set font size<br>
|
||||||
|
<a href="setkeywords.htm">SetKeywords</a> - associate keywords with document<br>
|
||||||
|
<a href="setleftmargin.htm">SetLeftMargin</a> - set left margin<br>
|
||||||
|
<a href="setlinewidth.htm">SetLineWidth</a> - set line width<br>
|
||||||
|
<a href="setlink.htm">SetLink</a> - set internal link destination<br>
|
||||||
|
<a href="setmargins.htm">SetMargins</a> - set margins<br>
|
||||||
|
<a href="setrightmargin.htm">SetRightMargin</a> - set right margin<br>
|
||||||
|
<a href="setsubject.htm">SetSubject</a> - set document subject<br>
|
||||||
|
<a href="settextcolor.htm">SetTextColor</a> - set text color<br>
|
||||||
|
<a href="settitle.htm">SetTitle</a> - set document title<br>
|
||||||
|
<a href="settopmargin.htm">SetTopMargin</a> - set top margin<br>
|
||||||
|
<a href="setx.htm">SetX</a> - set current x position<br>
|
||||||
|
<a href="setxy.htm">SetXY</a> - set current x and y positions<br>
|
||||||
|
<a href="sety.htm">SetY</a> - set current y position and optionally reset x<br>
|
||||||
|
<a href="text.htm">Text</a> - print a string<br>
|
||||||
|
<a href="write.htm">Write</a> - print flowing text<br>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
38
application/libraries/fpdf/doc/line.htm
Normal file
38
application/libraries/fpdf/doc/line.htm
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Line</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Line</h1>
|
||||||
|
<code>Line(<b>float</b> x1, <b>float</b> y1, <b>float</b> x2, <b>float</b> y2)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Draws a line between two points.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>x1</code></dt>
|
||||||
|
<dd>
|
||||||
|
Abscissa of first point.
|
||||||
|
</dd>
|
||||||
|
<dt><code>y1</code></dt>
|
||||||
|
<dd>
|
||||||
|
Ordinate of first point.
|
||||||
|
</dd>
|
||||||
|
<dt><code>x2</code></dt>
|
||||||
|
<dd>
|
||||||
|
Abscissa of second point.
|
||||||
|
</dd>
|
||||||
|
<dt><code>y2</code></dt>
|
||||||
|
<dd>
|
||||||
|
Ordinate of second point.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setlinewidth.htm">SetLineWidth</a>,
|
||||||
|
<a href="setdrawcolor.htm">SetDrawColor</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
46
application/libraries/fpdf/doc/link.htm
Normal file
46
application/libraries/fpdf/doc/link.htm
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Link</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Link</h1>
|
||||||
|
<code>Link(<b>float</b> x, <b>float</b> y, <b>float</b> w, <b>float</b> h, <b>mixed</b> link)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Puts a link on a rectangular area of the page. Text or image links are generally put via Cell(),
|
||||||
|
Write() or Image(), but this method can be useful for instance to define a clickable area inside
|
||||||
|
an image.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>x</code></dt>
|
||||||
|
<dd>
|
||||||
|
Abscissa of the upper-left corner of the rectangle.
|
||||||
|
</dd>
|
||||||
|
<dt><code>y</code></dt>
|
||||||
|
<dd>
|
||||||
|
Ordinate of the upper-left corner of the rectangle.
|
||||||
|
</dd>
|
||||||
|
<dt><code>w</code></dt>
|
||||||
|
<dd>
|
||||||
|
Width of the rectangle.
|
||||||
|
</dd>
|
||||||
|
<dt><code>h</code></dt>
|
||||||
|
<dd>
|
||||||
|
Height of the rectangle.
|
||||||
|
</dd>
|
||||||
|
<dt><code>link</code></dt>
|
||||||
|
<dd>
|
||||||
|
URL or identifier returned by AddLink().
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="addlink.htm">AddLink</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="write.htm">Write</a>,
|
||||||
|
<a href="image.htm">Image</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
28
application/libraries/fpdf/doc/ln.htm
Normal file
28
application/libraries/fpdf/doc/ln.htm
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Ln</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Ln</h1>
|
||||||
|
<code>Ln([<b>float</b> h])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Performs a line break. The current abscissa goes back to the left margin and the ordinate
|
||||||
|
increases by the amount passed in parameter.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>h</code></dt>
|
||||||
|
<dd>
|
||||||
|
The height of the break.
|
||||||
|
<br>
|
||||||
|
By default, the value equals the height of the last printed cell.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="cell.htm">Cell</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
76
application/libraries/fpdf/doc/multicell.htm
Normal file
76
application/libraries/fpdf/doc/multicell.htm
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>MultiCell</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>MultiCell</h1>
|
||||||
|
<code>MultiCell(<b>float</b> w, <b>float</b> h, <b>string</b> txt [, <b>mixed</b> border [, <b>string</b> align [, <b>boolean</b> fill]]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
This method allows printing text with line breaks. They can be automatic (as soon as the
|
||||||
|
text reaches the right border of the cell) or explicit (via the \n character). As many cells
|
||||||
|
as necessary are output, one below the other.
|
||||||
|
<br>
|
||||||
|
Text can be aligned, centered or justified. The cell block can be framed and the background
|
||||||
|
painted.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>w</code></dt>
|
||||||
|
<dd>
|
||||||
|
Width of cells. If <code>0</code>, they extend up to the right margin of the page.
|
||||||
|
</dd>
|
||||||
|
<dt><code>h</code></dt>
|
||||||
|
<dd>
|
||||||
|
Height of cells.
|
||||||
|
</dd>
|
||||||
|
<dt><code>txt</code></dt>
|
||||||
|
<dd>
|
||||||
|
String to print.
|
||||||
|
</dd>
|
||||||
|
<dt><code>border</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if borders must be drawn around the cell block. The value can be either a number:
|
||||||
|
<ul>
|
||||||
|
<li><code>0</code>: no border</li>
|
||||||
|
<li><code>1</code>: frame</li>
|
||||||
|
</ul>
|
||||||
|
or a string containing some or all of the following characters (in any order):
|
||||||
|
<ul>
|
||||||
|
<li><code>L</code>: left</li>
|
||||||
|
<li><code>T</code>: top</li>
|
||||||
|
<li><code>R</code>: right</li>
|
||||||
|
<li><code>B</code>: bottom</li>
|
||||||
|
</ul>
|
||||||
|
Default value: <code>0</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>align</code></dt>
|
||||||
|
<dd>
|
||||||
|
Sets the text alignment. Possible values are:
|
||||||
|
<ul>
|
||||||
|
<li><code>L</code>: left alignment</li>
|
||||||
|
<li><code>C</code>: center</li>
|
||||||
|
<li><code>R</code>: right alignment</li>
|
||||||
|
<li><code>J</code>: justification (default value)</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
<dt><code>fill</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if the cell background must be painted (<code>true</code>) or transparent (<code>false</code>).
|
||||||
|
Default value: <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setfont.htm">SetFont</a>,
|
||||||
|
<a href="setdrawcolor.htm">SetDrawColor</a>,
|
||||||
|
<a href="setfillcolor.htm">SetFillColor</a>,
|
||||||
|
<a href="settextcolor.htm">SetTextColor</a>,
|
||||||
|
<a href="setlinewidth.htm">SetLineWidth</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="write.htm">Write</a>,
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
46
application/libraries/fpdf/doc/output.htm
Normal file
46
application/libraries/fpdf/doc/output.htm
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Output</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Output</h1>
|
||||||
|
<code><b>string</b> Output([<b>string</b> dest [, <b>string</b> name [, <b>boolean</b> isUTF8]]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Send the document to a given destination: browser, file or string. In the case of a browser, the
|
||||||
|
PDF viewer may be used or a download may be forced.
|
||||||
|
<br>
|
||||||
|
The method first calls Close() if necessary to terminate the document.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>dest</code></dt>
|
||||||
|
<dd>
|
||||||
|
Destination where to send the document. It can be one of the following:
|
||||||
|
<ul>
|
||||||
|
<li><code>I</code>: send the file inline to the browser. The PDF viewer is used if available.</li>
|
||||||
|
<li><code>D</code>: send to the browser and force a file download with the name given by <code>name</code>.</li>
|
||||||
|
<li><code>F</code>: save to a local file with the name given by <code>name</code> (may include a path).</li>
|
||||||
|
<li><code>S</code>: return the document as a string.</li>
|
||||||
|
</ul>
|
||||||
|
The default value is <code>I</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>name</code></dt>
|
||||||
|
<dd>
|
||||||
|
The name of the file. It is ignored in case of destination <code>S</code>.<br>
|
||||||
|
The default value is <code>doc.pdf</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>isUTF8</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if <code>name</code> is encoded in ISO-8859-1 (<code>false</code>) or UTF-8 (<code>true</code>).
|
||||||
|
Only used for destinations <code>I</code> and <code>D</code>.<br>
|
||||||
|
The default value is <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="close.htm">Close</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
application/libraries/fpdf/doc/pageno.htm
Normal file
18
application/libraries/fpdf/doc/pageno.htm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>PageNo</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>PageNo</h1>
|
||||||
|
<code><b>int</b> PageNo()</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Returns the current page number.
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="aliasnbpages.htm">AliasNbPages</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
48
application/libraries/fpdf/doc/rect.htm
Normal file
48
application/libraries/fpdf/doc/rect.htm
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Rect</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Rect</h1>
|
||||||
|
<code>Rect(<b>float</b> x, <b>float</b> y, <b>float</b> w, <b>float</b> h [, <b>string</b> style])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Outputs a rectangle. It can be drawn (border only), filled (with no border) or both.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>x</code></dt>
|
||||||
|
<dd>
|
||||||
|
Abscissa of upper-left corner.
|
||||||
|
</dd>
|
||||||
|
<dt><code>y</code></dt>
|
||||||
|
<dd>
|
||||||
|
Ordinate of upper-left corner.
|
||||||
|
</dd>
|
||||||
|
<dt><code>w</code></dt>
|
||||||
|
<dd>
|
||||||
|
Width.
|
||||||
|
</dd>
|
||||||
|
<dt><code>h</code></dt>
|
||||||
|
<dd>
|
||||||
|
Height.
|
||||||
|
</dd>
|
||||||
|
<dt><code>style</code></dt>
|
||||||
|
<dd>
|
||||||
|
Style of rendering. Possible values are:
|
||||||
|
<ul>
|
||||||
|
<li><code>D</code> or empty string: draw. This is the default value.</li>
|
||||||
|
<li><code>F</code>: fill</li>
|
||||||
|
<li><code>DF</code> or <code>FD</code>: draw and fill</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setlinewidth.htm">SetLineWidth</a>,
|
||||||
|
<a href="setdrawcolor.htm">SetDrawColor</a>,
|
||||||
|
<a href="setfillcolor.htm">SetFillColor</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
application/libraries/fpdf/doc/setauthor.htm
Normal file
33
application/libraries/fpdf/doc/setauthor.htm
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetAuthor</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetAuthor</h1>
|
||||||
|
<code>SetAuthor(<b>string</b> author [, <b>boolean</b> isUTF8])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the author of the document.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>author</code></dt>
|
||||||
|
<dd>
|
||||||
|
The name of the author.
|
||||||
|
</dd>
|
||||||
|
<dt><code>isUTF8</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if the string is encoded in ISO-8859-1 (<code>false</code>) or UTF-8 (<code>true</code>).<br>
|
||||||
|
Default value: <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setcreator.htm">SetCreator</a>,
|
||||||
|
<a href="setkeywords.htm">SetKeywords</a>,
|
||||||
|
<a href="setsubject.htm">SetSubject</a>,
|
||||||
|
<a href="settitle.htm">SetTitle</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
application/libraries/fpdf/doc/setautopagebreak.htm
Normal file
33
application/libraries/fpdf/doc/setautopagebreak.htm
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetAutoPageBreak</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetAutoPageBreak</h1>
|
||||||
|
<code>SetAutoPageBreak(<b>boolean</b> auto [, <b>float</b> margin])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Enables or disables the automatic page breaking mode. When enabling, the second parameter is
|
||||||
|
the distance from the bottom of the page that defines the triggering limit. By default, the
|
||||||
|
mode is on and the margin is 2 cm.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>auto</code></dt>
|
||||||
|
<dd>
|
||||||
|
Boolean indicating if mode should be on or off.
|
||||||
|
</dd>
|
||||||
|
<dt><code>margin</code></dt>
|
||||||
|
<dd>
|
||||||
|
Distance from the bottom of the page.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>,
|
||||||
|
<a href="acceptpagebreak.htm">AcceptPageBreak</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
31
application/libraries/fpdf/doc/setcompression.htm
Normal file
31
application/libraries/fpdf/doc/setcompression.htm
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetCompression</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetCompression</h1>
|
||||||
|
<code>SetCompression(<b>boolean</b> compress)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Activates or deactivates page compression. When activated, the internal representation of
|
||||||
|
each page is compressed, which leads to a compression ratio of about 2 for the resulting
|
||||||
|
document.
|
||||||
|
<br>
|
||||||
|
Compression is on by default.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<strong>Note:</strong> the Zlib extension is required for this feature. If not present, compression
|
||||||
|
will be turned off.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>compress</code></dt>
|
||||||
|
<dd>
|
||||||
|
Boolean indicating if compression must be enabled.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
34
application/libraries/fpdf/doc/setcreator.htm
Normal file
34
application/libraries/fpdf/doc/setcreator.htm
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetCreator</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetCreator</h1>
|
||||||
|
<code>SetCreator(<b>string</b> creator [, <b>boolean</b> isUTF8])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the creator of the document. This is typically the name of the application that
|
||||||
|
generates the PDF.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>creator</code></dt>
|
||||||
|
<dd>
|
||||||
|
The name of the creator.
|
||||||
|
</dd>
|
||||||
|
<dt><code>isUTF8</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if the string is encoded in ISO-8859-1 (<code>false</code>) or UTF-8 (<code>true</code>).<br>
|
||||||
|
Default value: <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setauthor.htm">SetAuthor</a>,
|
||||||
|
<a href="setkeywords.htm">SetKeywords</a>,
|
||||||
|
<a href="setsubject.htm">SetSubject</a>,
|
||||||
|
<a href="settitle.htm">SetTitle</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
45
application/libraries/fpdf/doc/setdisplaymode.htm
Normal file
45
application/libraries/fpdf/doc/setdisplaymode.htm
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetDisplayMode</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetDisplayMode</h1>
|
||||||
|
<code>SetDisplayMode(<b>mixed</b> zoom [, <b>string</b> layout])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the way the document is to be displayed by the viewer. The zoom level can be set: pages can be
|
||||||
|
displayed entirely on screen, occupy the full width of the window, use real size, be scaled by a
|
||||||
|
specific zooming factor or use viewer default (configured in the Preferences menu of Adobe Reader).
|
||||||
|
The page layout can be specified too: single at once, continuous display, two columns or viewer
|
||||||
|
default.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>zoom</code></dt>
|
||||||
|
<dd>
|
||||||
|
The zoom to use. It can be one of the following string values:
|
||||||
|
<ul>
|
||||||
|
<li><code>fullpage</code>: displays the entire page on screen</li>
|
||||||
|
<li><code>fullwidth</code>: uses maximum width of window</li>
|
||||||
|
<li><code>real</code>: uses real size (equivalent to 100% zoom)</li>
|
||||||
|
<li><code>default</code>: uses viewer default mode</li>
|
||||||
|
</ul>
|
||||||
|
or a number indicating the zooming factor to use.
|
||||||
|
</dd>
|
||||||
|
<dt><code>layout</code></dt>
|
||||||
|
<dd>
|
||||||
|
The page layout. Possible values are:
|
||||||
|
<ul>
|
||||||
|
<li><code>single</code>: displays one page at once</li>
|
||||||
|
<li><code>continuous</code>: displays pages continuously</li>
|
||||||
|
<li><code>two</code>: displays two pages on two columns</li>
|
||||||
|
<li><code>default</code>: uses viewer default mode</li>
|
||||||
|
</ul>
|
||||||
|
Default value is <code>default</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
41
application/libraries/fpdf/doc/setdrawcolor.htm
Normal file
41
application/libraries/fpdf/doc/setdrawcolor.htm
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetDrawColor</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetDrawColor</h1>
|
||||||
|
<code>SetDrawColor(<b>int</b> r [, <b>int</b> g, <b>int</b> b])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the color used for all drawing operations (lines, rectangles and cell borders). It
|
||||||
|
can be expressed in RGB components or gray scale. The method can be called before the first
|
||||||
|
page is created and the value is retained from page to page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>r</code></dt>
|
||||||
|
<dd>
|
||||||
|
If <code>g</code> et <code>b</code> are given, red component; if not, indicates the gray level.
|
||||||
|
Value between 0 and 255.
|
||||||
|
</dd>
|
||||||
|
<dt><code>g</code></dt>
|
||||||
|
<dd>
|
||||||
|
Green component (between 0 and 255).
|
||||||
|
</dd>
|
||||||
|
<dt><code>b</code></dt>
|
||||||
|
<dd>
|
||||||
|
Blue component (between 0 and 255).
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setfillcolor.htm">SetFillColor</a>,
|
||||||
|
<a href="settextcolor.htm">SetTextColor</a>,
|
||||||
|
<a href="line.htm">Line</a>,
|
||||||
|
<a href="rect.htm">Rect</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
40
application/libraries/fpdf/doc/setfillcolor.htm
Normal file
40
application/libraries/fpdf/doc/setfillcolor.htm
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetFillColor</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetFillColor</h1>
|
||||||
|
<code>SetFillColor(<b>int</b> r [, <b>int</b> g, <b>int</b> b])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the color used for all filling operations (filled rectangles and cell backgrounds).
|
||||||
|
It can be expressed in RGB components or gray scale. The method can be called before the first
|
||||||
|
page is created and the value is retained from page to page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>r</code></dt>
|
||||||
|
<dd>
|
||||||
|
If <code>g</code> and <code>b</code> are given, red component; if not, indicates the gray level.
|
||||||
|
Value between 0 and 255.
|
||||||
|
</dd>
|
||||||
|
<dt><code>g</code></dt>
|
||||||
|
<dd>
|
||||||
|
Green component (between 0 and 255).
|
||||||
|
</dd>
|
||||||
|
<dt><code>b</code></dt>
|
||||||
|
<dd>
|
||||||
|
Blue component (between 0 and 255).
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setdrawcolor.htm">SetDrawColor</a>,
|
||||||
|
<a href="settextcolor.htm">SetTextColor</a>,
|
||||||
|
<a href="rect.htm">Rect</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
92
application/libraries/fpdf/doc/setfont.htm
Normal file
92
application/libraries/fpdf/doc/setfont.htm
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetFont</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetFont</h1>
|
||||||
|
<code>SetFont(<b>string</b> family [, <b>string</b> style [, <b>float</b> size]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Sets the font used to print character strings. It is mandatory to call this method
|
||||||
|
at least once before printing text or the resulting document would not be valid.
|
||||||
|
<br>
|
||||||
|
The font can be either a standard one or a font added via the AddFont() method. Standard fonts
|
||||||
|
use the Windows encoding cp1252 (Western Europe).
|
||||||
|
<br>
|
||||||
|
The method can be called before the first page is created and the font is kept from page
|
||||||
|
to page.
|
||||||
|
<br>
|
||||||
|
If you just wish to change the current font size, it is simpler to call SetFontSize().
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<strong>Note:</strong> the font definition files must be accessible. They are searched successively in:
|
||||||
|
<ul>
|
||||||
|
<li>The directory defined by the <code>FPDF_FONTPATH</code> constant (if this constant is defined)</li>
|
||||||
|
<li>The <code>font</code> directory located in the same directory as <code>fpdf.php</code> (if it exists)</li>
|
||||||
|
<li>The directories accessible through <code>include()</code></li>
|
||||||
|
</ul>
|
||||||
|
Example using <code>FPDF_FONTPATH</code>:
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>define('FPDF_FONTPATH','/home/www/font');
|
||||||
|
require('fpdf.php');</code></pre>
|
||||||
|
</div>
|
||||||
|
If the file corresponding to the requested font is not found, the error "Could not include font
|
||||||
|
definition file" is raised.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>family</code></dt>
|
||||||
|
<dd>
|
||||||
|
Family font. It can be either a name defined by AddFont() or one of the standard families (case
|
||||||
|
insensitive):
|
||||||
|
<ul>
|
||||||
|
<li><code>Courier</code> (fixed-width)</li>
|
||||||
|
<li><code>Helvetica</code> or <code>Arial</code> (synonymous; sans serif)</li>
|
||||||
|
<li><code>Times</code> (serif)</li>
|
||||||
|
<li><code>Symbol</code> (symbolic)</li>
|
||||||
|
<li><code>ZapfDingbats</code> (symbolic)</li>
|
||||||
|
</ul>
|
||||||
|
It is also possible to pass an empty string. In that case, the current family is kept.
|
||||||
|
</dd>
|
||||||
|
<dt><code>style</code></dt>
|
||||||
|
<dd>
|
||||||
|
Font style. Possible values are (case insensitive):
|
||||||
|
<ul>
|
||||||
|
<li>empty string: regular</li>
|
||||||
|
<li><code>B</code>: bold</li>
|
||||||
|
<li><code>I</code>: italic</li>
|
||||||
|
<li><code>U</code>: underline</li>
|
||||||
|
</ul>
|
||||||
|
or any combination. The default value is regular.
|
||||||
|
Bold and italic styles do not apply to <code>Symbol</code> and <code>ZapfDingbats</code>.
|
||||||
|
</dd>
|
||||||
|
<dt><code>size</code></dt>
|
||||||
|
<dd>
|
||||||
|
Font size in points.
|
||||||
|
<br>
|
||||||
|
The default value is the current size. If no size has been specified since the beginning of
|
||||||
|
the document, the value taken is 12.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>// Times regular 12
|
||||||
|
$pdf->SetFont('Times');
|
||||||
|
// Arial bold 14
|
||||||
|
$pdf->SetFont('Arial','B',14);
|
||||||
|
// Removes bold
|
||||||
|
$pdf->SetFont('');
|
||||||
|
// Times bold, italic and underlined 14
|
||||||
|
$pdf->SetFont('Times','BIU');</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="addfont.htm">AddFont</a>,
|
||||||
|
<a href="setfontsize.htm">SetFontSize</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>,
|
||||||
|
<a href="write.htm">Write</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
25
application/libraries/fpdf/doc/setfontsize.htm
Normal file
25
application/libraries/fpdf/doc/setfontsize.htm
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetFontSize</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetFontSize</h1>
|
||||||
|
<code>SetFontSize(<b>float</b> size)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the size of the current font.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>size</code></dt>
|
||||||
|
<dd>
|
||||||
|
The size (in points).
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setfont.htm">SetFont</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
application/libraries/fpdf/doc/setkeywords.htm
Normal file
33
application/libraries/fpdf/doc/setkeywords.htm
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetKeywords</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetKeywords</h1>
|
||||||
|
<code>SetKeywords(<b>string</b> keywords [, <b>boolean</b> isUTF8])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>keywords</code></dt>
|
||||||
|
<dd>
|
||||||
|
The list of keywords.
|
||||||
|
</dd>
|
||||||
|
<dt><code>isUTF8</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if the string is encoded in ISO-8859-1 (<code>false</code>) or UTF-8 (<code>true</code>).<br>
|
||||||
|
Default value: <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setauthor.htm">SetAuthor</a>,
|
||||||
|
<a href="setcreator.htm">SetCreator</a>,
|
||||||
|
<a href="setsubject.htm">SetSubject</a>,
|
||||||
|
<a href="settitle.htm">SetTitle</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
30
application/libraries/fpdf/doc/setleftmargin.htm
Normal file
30
application/libraries/fpdf/doc/setleftmargin.htm
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetLeftMargin</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetLeftMargin</h1>
|
||||||
|
<code>SetLeftMargin(<b>float</b> margin)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the left margin. The method can be called before creating the first page.
|
||||||
|
<br>
|
||||||
|
If the current abscissa gets out of page, it is brought back to the margin.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>margin</code></dt>
|
||||||
|
<dd>
|
||||||
|
The margin.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="settopmargin.htm">SetTopMargin</a>,
|
||||||
|
<a href="setrightmargin.htm">SetRightMargin</a>,
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>,
|
||||||
|
<a href="setmargins.htm">SetMargins</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
29
application/libraries/fpdf/doc/setlinewidth.htm
Normal file
29
application/libraries/fpdf/doc/setlinewidth.htm
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetLineWidth</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetLineWidth</h1>
|
||||||
|
<code>SetLineWidth(<b>float</b> width)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the line width. By default, the value equals 0.2 mm. The method can be called before
|
||||||
|
the first page is created and the value is retained from page to page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>width</code></dt>
|
||||||
|
<dd>
|
||||||
|
The width.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="line.htm">Line</a>,
|
||||||
|
<a href="rect.htm">Rect</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
34
application/libraries/fpdf/doc/setlink.htm
Normal file
34
application/libraries/fpdf/doc/setlink.htm
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetLink</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetLink</h1>
|
||||||
|
<code>SetLink(<b>int</b> link [, <b>float</b> y [, <b>int</b> page]])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the page and position a link points to.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>link</code></dt>
|
||||||
|
<dd>
|
||||||
|
The link identifier returned by AddLink().
|
||||||
|
</dd>
|
||||||
|
<dt><code>y</code></dt>
|
||||||
|
<dd>
|
||||||
|
Ordinate of target position; <code>-1</code> indicates the current position.
|
||||||
|
The default value is <code>0</code> (top of page).
|
||||||
|
</dd>
|
||||||
|
<dt><code>page</code></dt>
|
||||||
|
<dd>
|
||||||
|
Number of target page; <code>-1</code> indicates the current page. This is the default value.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="addlink.htm">AddLink</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
37
application/libraries/fpdf/doc/setmargins.htm
Normal file
37
application/libraries/fpdf/doc/setmargins.htm
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetMargins</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetMargins</h1>
|
||||||
|
<code>SetMargins(<b>float</b> left, <b>float</b> top [, <b>float</b> right])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the left, top and right margins. By default, they equal 1 cm. Call this method to change
|
||||||
|
them.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>left</code></dt>
|
||||||
|
<dd>
|
||||||
|
Left margin.
|
||||||
|
</dd>
|
||||||
|
<dt><code>top</code></dt>
|
||||||
|
<dd>
|
||||||
|
Top margin.
|
||||||
|
</dd>
|
||||||
|
<dt><code>right</code></dt>
|
||||||
|
<dd>
|
||||||
|
Right margin. Default value is the left one.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setleftmargin.htm">SetLeftMargin</a>,
|
||||||
|
<a href="settopmargin.htm">SetTopMargin</a>,
|
||||||
|
<a href="setrightmargin.htm">SetRightMargin</a>,
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
28
application/libraries/fpdf/doc/setrightmargin.htm
Normal file
28
application/libraries/fpdf/doc/setrightmargin.htm
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetRightMargin</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetRightMargin</h1>
|
||||||
|
<code>SetRightMargin(<b>float</b> margin)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the right margin. The method can be called before creating the first page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>margin</code></dt>
|
||||||
|
<dd>
|
||||||
|
The margin.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setleftmargin.htm">SetLeftMargin</a>,
|
||||||
|
<a href="settopmargin.htm">SetTopMargin</a>,
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>,
|
||||||
|
<a href="setmargins.htm">SetMargins</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
application/libraries/fpdf/doc/setsubject.htm
Normal file
33
application/libraries/fpdf/doc/setsubject.htm
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetSubject</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetSubject</h1>
|
||||||
|
<code>SetSubject(<b>string</b> subject [, <b>boolean</b> isUTF8])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the subject of the document.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>subject</code></dt>
|
||||||
|
<dd>
|
||||||
|
The subject.
|
||||||
|
</dd>
|
||||||
|
<dt><code>isUTF8</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if the string is encoded in ISO-8859-1 (<code>false</code>) or UTF-8 (<code>true</code>).<br>
|
||||||
|
Default value: <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setauthor.htm">SetAuthor</a>,
|
||||||
|
<a href="setcreator.htm">SetCreator</a>,
|
||||||
|
<a href="setkeywords.htm">SetKeywords</a>,
|
||||||
|
<a href="settitle.htm">SetTitle</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
40
application/libraries/fpdf/doc/settextcolor.htm
Normal file
40
application/libraries/fpdf/doc/settextcolor.htm
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetTextColor</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetTextColor</h1>
|
||||||
|
<code>SetTextColor(<b>int</b> r [, <b>int</b> g, <b>int</b> b])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the color used for text. It can be expressed in RGB components or gray scale. The
|
||||||
|
method can be called before the first page is created and the value is retained from page to
|
||||||
|
page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>r</code></dt>
|
||||||
|
<dd>
|
||||||
|
If <code>g</code> et <code>b</code> are given, red component; if not, indicates the gray level.
|
||||||
|
Value between 0 and 255.
|
||||||
|
</dd>
|
||||||
|
<dt><code>g</code></dt>
|
||||||
|
<dd>
|
||||||
|
Green component (between 0 and 255).
|
||||||
|
</dd>
|
||||||
|
<dt><code>b</code></dt>
|
||||||
|
<dd>
|
||||||
|
Blue component (between 0 and 255).
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setdrawcolor.htm">SetDrawColor</a>,
|
||||||
|
<a href="setfillcolor.htm">SetFillColor</a>,
|
||||||
|
<a href="text.htm">Text</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
application/libraries/fpdf/doc/settitle.htm
Normal file
33
application/libraries/fpdf/doc/settitle.htm
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetTitle</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetTitle</h1>
|
||||||
|
<code>SetTitle(<b>string</b> title [, <b>boolean</b> isUTF8])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the title of the document.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>title</code></dt>
|
||||||
|
<dd>
|
||||||
|
The title.
|
||||||
|
</dd>
|
||||||
|
<dt><code>isUTF8</code></dt>
|
||||||
|
<dd>
|
||||||
|
Indicates if the string is encoded in ISO-8859-1 (<code>false</code>) or UTF-8 (<code>true</code>).<br>
|
||||||
|
Default value: <code>false</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setauthor.htm">SetAuthor</a>,
|
||||||
|
<a href="setcreator.htm">SetCreator</a>,
|
||||||
|
<a href="setkeywords.htm">SetKeywords</a>,
|
||||||
|
<a href="setsubject.htm">SetSubject</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
28
application/libraries/fpdf/doc/settopmargin.htm
Normal file
28
application/libraries/fpdf/doc/settopmargin.htm
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetTopMargin</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetTopMargin</h1>
|
||||||
|
<code>SetTopMargin(<b>float</b> margin)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the top margin. The method can be called before creating the first page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>margin</code></dt>
|
||||||
|
<dd>
|
||||||
|
The margin.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setleftmargin.htm">SetLeftMargin</a>,
|
||||||
|
<a href="setrightmargin.htm">SetRightMargin</a>,
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>,
|
||||||
|
<a href="setmargins.htm">SetMargins</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
29
application/libraries/fpdf/doc/setx.htm
Normal file
29
application/libraries/fpdf/doc/setx.htm
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetX</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetX</h1>
|
||||||
|
<code>SetX(<b>float</b> x)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the abscissa of the current position. If the passed value is negative, it is relative
|
||||||
|
to the right of the page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>x</code></dt>
|
||||||
|
<dd>
|
||||||
|
The value of the abscissa.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="getx.htm">GetX</a>,
|
||||||
|
<a href="gety.htm">GetY</a>,
|
||||||
|
<a href="sety.htm">SetY</a>,
|
||||||
|
<a href="setxy.htm">SetXY</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
31
application/libraries/fpdf/doc/setxy.htm
Normal file
31
application/libraries/fpdf/doc/setxy.htm
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetXY</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetXY</h1>
|
||||||
|
<code>SetXY(<b>float</b> x, <b>float</b> y)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Defines the abscissa and ordinate of the current position. If the passed values are negative,
|
||||||
|
they are relative respectively to the right and bottom of the page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>x</code></dt>
|
||||||
|
<dd>
|
||||||
|
The value of the abscissa.
|
||||||
|
</dd>
|
||||||
|
<dt><code>y</code></dt>
|
||||||
|
<dd>
|
||||||
|
The value of the ordinate.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setx.htm">SetX</a>,
|
||||||
|
<a href="sety.htm">SetY</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
application/libraries/fpdf/doc/sety.htm
Normal file
33
application/libraries/fpdf/doc/sety.htm
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>SetY</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SetY</h1>
|
||||||
|
<code>SetY(<b>float</b> y [, <b>boolean</b> resetX])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Sets the ordinate and optionally moves the current abscissa back to the left margin. If the value
|
||||||
|
is negative, it is relative to the bottom of the page.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>y</code></dt>
|
||||||
|
<dd>
|
||||||
|
The value of the ordinate.
|
||||||
|
</dd>
|
||||||
|
<dt><code>resetX</code></dt>
|
||||||
|
<dd>
|
||||||
|
Whether to reset the abscissa. Default value: <code>true</code>.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="getx.htm">GetX</a>,
|
||||||
|
<a href="gety.htm">GetY</a>,
|
||||||
|
<a href="setx.htm">SetX</a>,
|
||||||
|
<a href="setxy.htm">SetXY</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
39
application/libraries/fpdf/doc/text.htm
Normal file
39
application/libraries/fpdf/doc/text.htm
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Text</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Text</h1>
|
||||||
|
<code>Text(<b>float</b> x, <b>float</b> y, <b>string</b> txt)</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
Prints a character string. The origin is on the left of the first character, on the baseline.
|
||||||
|
This method allows to place a string precisely on the page, but it is usually easier to use
|
||||||
|
Cell(), MultiCell() or Write() which are the standard methods to print text.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>x</code></dt>
|
||||||
|
<dd>
|
||||||
|
Abscissa of the origin.
|
||||||
|
</dd>
|
||||||
|
<dt><code>y</code></dt>
|
||||||
|
<dd>
|
||||||
|
Ordinate of the origin.
|
||||||
|
</dd>
|
||||||
|
<dt><code>txt</code></dt>
|
||||||
|
<dd>
|
||||||
|
String to print.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setfont.htm">SetFont</a>,
|
||||||
|
<a href="settextcolor.htm">SetTextColor</a>,
|
||||||
|
<a href="cell.htm">Cell</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>,
|
||||||
|
<a href="write.htm">Write</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
51
application/libraries/fpdf/doc/write.htm
Normal file
51
application/libraries/fpdf/doc/write.htm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Write</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="../fpdf.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Write</h1>
|
||||||
|
<code>Write(<b>float</b> h, <b>string</b> txt [, <b>mixed</b> link])</code>
|
||||||
|
<h2>Description</h2>
|
||||||
|
This method prints text from the current position. When the right margin is reached (or the \n
|
||||||
|
character is met) a line break occurs and text continues from the left margin. Upon method exit,
|
||||||
|
the current position is left just at the end of the text.
|
||||||
|
<br>
|
||||||
|
It is possible to put a link on the text.
|
||||||
|
<h2>Parameters</h2>
|
||||||
|
<dl class="param">
|
||||||
|
<dt><code>h</code></dt>
|
||||||
|
<dd>
|
||||||
|
Line height.
|
||||||
|
</dd>
|
||||||
|
<dt><code>txt</code></dt>
|
||||||
|
<dd>
|
||||||
|
String to print.
|
||||||
|
</dd>
|
||||||
|
<dt><code>link</code></dt>
|
||||||
|
<dd>
|
||||||
|
URL or identifier returned by AddLink().
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Example</h2>
|
||||||
|
<div class="doc-source">
|
||||||
|
<pre><code>// Begin with regular font
|
||||||
|
$pdf->SetFont('Arial','',14);
|
||||||
|
$pdf->Write(5,'Visit ');
|
||||||
|
// Then put a blue underlined link
|
||||||
|
$pdf->SetTextColor(0,0,255);
|
||||||
|
$pdf->SetFont('','U');
|
||||||
|
$pdf->Write(5,'www.fpdf.org','http://www.fpdf.org');</code></pre>
|
||||||
|
</div>
|
||||||
|
<h2>See also</h2>
|
||||||
|
<a href="setfont.htm">SetFont</a>,
|
||||||
|
<a href="settextcolor.htm">SetTextColor</a>,
|
||||||
|
<a href="addlink.htm">AddLink</a>,
|
||||||
|
<a href="multicell.htm">MultiCell</a>,
|
||||||
|
<a href="setautopagebreak.htm">SetAutoPageBreak</a>
|
||||||
|
<hr style="margin-top:1.5em">
|
||||||
|
<div style="text-align:center"><a href="index.htm">Index</a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
10
application/libraries/fpdf/font/courier.php
Normal file
10
application/libraries/fpdf/font/courier.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Courier';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
for($i=0;$i<=255;$i++)
|
||||||
|
$cw[chr($i)] = 600;
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
10
application/libraries/fpdf/font/courierb.php
Normal file
10
application/libraries/fpdf/font/courierb.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Courier-Bold';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
for($i=0;$i<=255;$i++)
|
||||||
|
$cw[chr($i)] = 600;
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
10
application/libraries/fpdf/font/courierbi.php
Normal file
10
application/libraries/fpdf/font/courierbi.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Courier-BoldOblique';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
for($i=0;$i<=255;$i++)
|
||||||
|
$cw[chr($i)] = 600;
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
10
application/libraries/fpdf/font/courieri.php
Normal file
10
application/libraries/fpdf/font/courieri.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Courier-Oblique';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
for($i=0;$i<=255;$i++)
|
||||||
|
$cw[chr($i)] = 600;
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
21
application/libraries/fpdf/font/helvetica.php
Normal file
21
application/libraries/fpdf/font/helvetica.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Helvetica';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
$cw = array(
|
||||||
|
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
|
||||||
|
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
|
||||||
|
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
|
||||||
|
'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
|
||||||
|
'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
|
||||||
|
'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
|
||||||
|
chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
|
||||||
|
chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
|
||||||
|
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
|
||||||
|
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
|
||||||
|
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
|
||||||
|
chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
21
application/libraries/fpdf/font/helveticab.php
Normal file
21
application/libraries/fpdf/font/helveticab.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Helvetica-Bold';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
$cw = array(
|
||||||
|
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
|
||||||
|
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
|
||||||
|
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
|
||||||
|
'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
|
||||||
|
'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
|
||||||
|
'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
|
||||||
|
chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
|
||||||
|
chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
|
||||||
|
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
|
||||||
|
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
|
||||||
|
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
|
||||||
|
chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
21
application/libraries/fpdf/font/helveticabi.php
Normal file
21
application/libraries/fpdf/font/helveticabi.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Helvetica-BoldOblique';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
$cw = array(
|
||||||
|
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
|
||||||
|
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
|
||||||
|
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
|
||||||
|
'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
|
||||||
|
'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
|
||||||
|
'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
|
||||||
|
chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
|
||||||
|
chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
|
||||||
|
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
|
||||||
|
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
|
||||||
|
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
|
||||||
|
chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
21
application/libraries/fpdf/font/helveticai.php
Normal file
21
application/libraries/fpdf/font/helveticai.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Helvetica-Oblique';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
$cw = array(
|
||||||
|
chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
|
||||||
|
chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
|
||||||
|
','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
|
||||||
|
'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
|
||||||
|
'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
|
||||||
|
'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
|
||||||
|
chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
|
||||||
|
chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
|
||||||
|
chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
|
||||||
|
chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
|
||||||
|
chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
|
||||||
|
chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
20
application/libraries/fpdf/font/symbol.php
Normal file
20
application/libraries/fpdf/font/symbol.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Symbol';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
$cw = array(
|
||||||
|
chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
|
||||||
|
chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'\''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549,
|
||||||
|
','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722,
|
||||||
|
'B'=>667,'C'=>722,'D'=>612,'E'=>611,'F'=>763,'G'=>603,'H'=>722,'I'=>333,'J'=>631,'K'=>722,'L'=>686,'M'=>889,'N'=>722,'O'=>722,'P'=>768,'Q'=>741,'R'=>556,'S'=>592,'T'=>611,'U'=>690,'V'=>439,'W'=>768,
|
||||||
|
'X'=>645,'Y'=>795,'Z'=>611,'['=>333,'\\'=>863,']'=>333,'^'=>658,'_'=>500,'`'=>500,'a'=>631,'b'=>549,'c'=>549,'d'=>494,'e'=>439,'f'=>521,'g'=>411,'h'=>603,'i'=>329,'j'=>603,'k'=>549,'l'=>549,'m'=>576,
|
||||||
|
'n'=>521,'o'=>549,'p'=>549,'q'=>521,'r'=>549,'s'=>603,'t'=>439,'u'=>576,'v'=>713,'w'=>686,'x'=>493,'y'=>686,'z'=>494,'{'=>480,'|'=>200,'}'=>480,'~'=>549,chr(127)=>0,chr(128)=>0,chr(129)=>0,chr(130)=>0,chr(131)=>0,
|
||||||
|
chr(132)=>0,chr(133)=>0,chr(134)=>0,chr(135)=>0,chr(136)=>0,chr(137)=>0,chr(138)=>0,chr(139)=>0,chr(140)=>0,chr(141)=>0,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0,
|
||||||
|
chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>750,chr(161)=>620,chr(162)=>247,chr(163)=>549,chr(164)=>167,chr(165)=>713,chr(166)=>500,chr(167)=>753,chr(168)=>753,chr(169)=>753,chr(170)=>753,chr(171)=>1042,chr(172)=>987,chr(173)=>603,chr(174)=>987,chr(175)=>603,
|
||||||
|
chr(176)=>400,chr(177)=>549,chr(178)=>411,chr(179)=>549,chr(180)=>549,chr(181)=>713,chr(182)=>494,chr(183)=>460,chr(184)=>549,chr(185)=>549,chr(186)=>549,chr(187)=>549,chr(188)=>1000,chr(189)=>603,chr(190)=>1000,chr(191)=>658,chr(192)=>823,chr(193)=>686,chr(194)=>795,chr(195)=>987,chr(196)=>768,chr(197)=>768,
|
||||||
|
chr(198)=>823,chr(199)=>768,chr(200)=>768,chr(201)=>713,chr(202)=>713,chr(203)=>713,chr(204)=>713,chr(205)=>713,chr(206)=>713,chr(207)=>713,chr(208)=>768,chr(209)=>713,chr(210)=>790,chr(211)=>790,chr(212)=>890,chr(213)=>823,chr(214)=>549,chr(215)=>250,chr(216)=>713,chr(217)=>603,chr(218)=>603,chr(219)=>1042,
|
||||||
|
chr(220)=>987,chr(221)=>603,chr(222)=>987,chr(223)=>603,chr(224)=>494,chr(225)=>329,chr(226)=>790,chr(227)=>790,chr(228)=>786,chr(229)=>713,chr(230)=>384,chr(231)=>384,chr(232)=>384,chr(233)=>384,chr(234)=>384,chr(235)=>384,chr(236)=>494,chr(237)=>494,chr(238)=>494,chr(239)=>494,chr(240)=>0,chr(241)=>329,
|
||||||
|
chr(242)=>274,chr(243)=>686,chr(244)=>686,chr(245)=>686,chr(246)=>384,chr(247)=>384,chr(248)=>384,chr(249)=>384,chr(250)=>384,chr(251)=>384,chr(252)=>494,chr(253)=>494,chr(254)=>494,chr(255)=>0);
|
||||||
|
$uv = array(32=>160,33=>33,34=>8704,35=>35,36=>8707,37=>array(37,2),39=>8715,40=>array(40,2),42=>8727,43=>array(43,2),45=>8722,46=>array(46,18),64=>8773,65=>array(913,2),67=>935,68=>array(916,2),70=>934,71=>915,72=>919,73=>921,74=>977,75=>array(922,4),79=>array(927,2),81=>920,82=>929,83=>array(931,3),86=>962,87=>937,88=>926,89=>936,90=>918,91=>91,92=>8756,93=>93,94=>8869,95=>95,96=>63717,97=>array(945,2),99=>967,100=>array(948,2),102=>966,103=>947,104=>951,105=>953,106=>981,107=>array(954,4),111=>array(959,2),113=>952,114=>961,115=>array(963,3),118=>982,119=>969,120=>958,121=>968,122=>950,123=>array(123,3),126=>8764,160=>8364,161=>978,162=>8242,163=>8804,164=>8725,165=>8734,166=>402,167=>9827,168=>9830,169=>9829,170=>9824,171=>8596,172=>array(8592,4),176=>array(176,2),178=>8243,179=>8805,180=>215,181=>8733,182=>8706,183=>8226,184=>247,185=>array(8800,2),187=>8776,188=>8230,189=>array(63718,2),191=>8629,192=>8501,193=>8465,194=>8476,195=>8472,196=>8855,197=>8853,198=>8709,199=>array(8745,2),201=>8835,202=>8839,203=>8836,204=>8834,205=>8838,206=>array(8712,2),208=>8736,209=>8711,210=>63194,211=>63193,212=>63195,213=>8719,214=>8730,215=>8901,216=>172,217=>array(8743,2),219=>8660,220=>array(8656,4),224=>9674,225=>9001,226=>array(63720,3),229=>8721,230=>array(63723,10),241=>9002,242=>8747,243=>8992,244=>63733,245=>8993,246=>array(63734,9));
|
||||||
|
?>
|
||||||
21
application/libraries/fpdf/font/times.php
Normal file
21
application/libraries/fpdf/font/times.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
$type = 'Core';
|
||||||
|
$name = 'Times-Roman';
|
||||||
|
$up = -100;
|
||||||
|
$ut = 50;
|
||||||
|
$cw = array(
|
||||||
|
chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
|
||||||
|
chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>408,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>180,'('=>333,')'=>333,'*'=>500,'+'=>564,
|
||||||
|
','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>564,'='=>564,'>'=>564,'?'=>444,'@'=>921,'A'=>722,
|
||||||
|
'B'=>667,'C'=>667,'D'=>722,'E'=>611,'F'=>556,'G'=>722,'H'=>722,'I'=>333,'J'=>389,'K'=>722,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>556,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>722,'W'=>944,
|
||||||
|
'X'=>722,'Y'=>722,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>469,'_'=>500,'`'=>333,'a'=>444,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778,
|
||||||
|
'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>333,'s'=>389,'t'=>278,'u'=>500,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>480,'|'=>200,'}'=>480,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
|
||||||
|
chr(132)=>444,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>889,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>444,chr(148)=>444,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>980,
|
||||||
|
chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>200,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>564,chr(173)=>333,chr(174)=>760,chr(175)=>333,
|
||||||
|
chr(176)=>400,chr(177)=>564,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>453,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>444,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
|
||||||
|
chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>564,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
|
||||||
|
chr(220)=>722,chr(221)=>722,chr(222)=>556,chr(223)=>500,chr(224)=>444,chr(225)=>444,chr(226)=>444,chr(227)=>444,chr(228)=>444,chr(229)=>444,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500,
|
||||||
|
chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>564,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>500,chr(254)=>500,chr(255)=>500);
|
||||||
|
$enc = 'cp1252';
|
||||||
|
$uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
|
||||||
|
?>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user