diff --git a/addons/kosbar_purchase_finance/__init__.py b/addons/kosbar_purchase_finance/__init__.py
new file mode 100644
index 0000000..0650744
--- /dev/null
+++ b/addons/kosbar_purchase_finance/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/addons/kosbar_purchase_finance/__manifest__.py b/addons/kosbar_purchase_finance/__manifest__.py
new file mode 100644
index 0000000..faa5189
--- /dev/null
+++ b/addons/kosbar_purchase_finance/__manifest__.py
@@ -0,0 +1,18 @@
+{
+ 'name': 'Kos Barokah Purchase Finance',
+ 'version': '1.0',
+ 'category': 'Purchases',
+ 'summary': 'Permintaan barang gudang + approval PO oleh Finance',
+ 'author': 'Kos Barokah',
+ 'license': 'LGPL-3',
+ 'depends': ['purchase', 'stock', 'product', 'kosbar_erp_ext'],
+ 'data': [
+ 'security/res_groups.xml',
+ 'security/ir.model.access.csv',
+ 'data/ir_sequence.xml',
+ 'views/purchase_request_views.xml',
+ 'views/purchase_order_views.xml',
+ ],
+ 'installable': True,
+ 'application': False,
+}
diff --git a/addons/kosbar_purchase_finance/data/ir_sequence.xml b/addons/kosbar_purchase_finance/data/ir_sequence.xml
new file mode 100644
index 0000000..773fa90
--- /dev/null
+++ b/addons/kosbar_purchase_finance/data/ir_sequence.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ Purchase Request Kos Barokah
+ kosbar.purchase.request
+ 5
+ PR/%(year)s/
+
+
+
diff --git a/addons/kosbar_purchase_finance/models/__init__.py b/addons/kosbar_purchase_finance/models/__init__.py
new file mode 100644
index 0000000..4a7af97
--- /dev/null
+++ b/addons/kosbar_purchase_finance/models/__init__.py
@@ -0,0 +1,2 @@
+from . import purchase_request
+from . import purchase_order
diff --git a/addons/kosbar_purchase_finance/models/purchase_order.py b/addons/kosbar_purchase_finance/models/purchase_order.py
new file mode 100644
index 0000000..656a8c8
--- /dev/null
+++ b/addons/kosbar_purchase_finance/models/purchase_order.py
@@ -0,0 +1,24 @@
+from odoo import models, fields, api
+
+
+class PurchaseOrder(models.Model):
+ _inherit = 'purchase.order'
+
+ finance_state = fields.Selection([
+ ('pending', 'Pending Approval'),
+ ('approved', 'Finance Approved'),
+ ('rejected', 'Rejected'),
+ ], string='Status Finance', default='pending', tracking=True)
+
+ def action_finance_approve(self):
+ """Finance mengklik ini setelah review PO."""
+ return self.write({'finance_state': 'approved'})
+
+ def action_finance_reject(self):
+ """Finance menolak PO — ada catatan di notes."""
+ return self.write({'finance_state': 'rejected'})
+
+ @api.model
+ def _get_state_color(self):
+ # optional: styling di kanban view
+ return {'pending': 'warning', 'approved': 'success', 'rejected': 'danger'}
diff --git a/addons/kosbar_purchase_finance/models/purchase_request.py b/addons/kosbar_purchase_finance/models/purchase_request.py
new file mode 100644
index 0000000..8b6da11
--- /dev/null
+++ b/addons/kosbar_purchase_finance/models/purchase_request.py
@@ -0,0 +1,79 @@
+from odoo import models, fields, api
+
+
+class PurchaseRequest(models.Model):
+ _name = 'kosbar.purchase.request'
+ _description = 'Purchase Request dari Gudang'
+ _order = 'id desc'
+
+ name = fields.Char(
+ string='Nomor Request',
+ required=True,
+ copy=False,
+ readonly=True,
+ default='New',
+ )
+ user_id = fields.Many2one(
+ 'res.users',
+ string='Diminta Oleh',
+ default=lambda self: self.env.user,
+ required=True,
+ )
+ date_required = fields.Date(string='Tanggal Dibutuhkan', default=fields.Date.today())
+ state = fields.Selection([
+ ('draft', 'Draft'),
+ ('submitted', 'Submitted'),
+ ('approved', 'Approved / In Progress'),
+ ('done', 'Done'),
+ ('rejected', 'Rejected'),
+ ], string='Status', default='draft', tracking=True)
+
+ line_ids = fields.One2many(
+ 'kosbar.purchase.request.line',
+ 'request_id',
+ string='Daftar Barang',
+ )
+ notes = fields.Text(string='Catatan / Keperluan')
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ for vals in vals_list:
+ if vals.get('name', 'New') == 'New':
+ seq = self.env['ir.sequence'].next_by_code('kosbar.purchase.request')
+ vals['name'] = seq if seq else 'PR/2026/00001'
+ return super().create(vals_list)
+
+ def action_submit(self):
+ self.write({'state': 'submitted'})
+
+ def action_approve(self):
+ self.write({'state': 'approved'})
+
+ def action_done(self):
+ self.write({'state': 'done'})
+
+ def action_reject(self):
+ self.write({'state': 'rejected'})
+
+ def action_draft(self):
+ self.write({'state': 'draft'})
+
+
+class PurchaseRequestLine(models.Model):
+ _name = 'kosbar.purchase.request.line'
+ _description = 'Detail Item Purchase Request'
+
+ request_id = fields.Many2one('kosbar.purchase.request', string='Request Reference', ondelete='cascade')
+
+ # Bisa pilih barang existing ATAU buat barang baru langsung
+ is_new_product = fields.Boolean(string='Barang Baru?', default=False)
+ product_id = fields.Many2one('product.product', string='Produk (Existing)')
+
+ # Jika barang baru
+ new_product_name = fields.Char(string='Nama Barang Baru')
+ categ_id = fields.Many2one('product.category', string='Kategori Barang')
+
+ product_qty = fields.Float(string='Jumlah', default=1.0, required=True)
+ product_uom = fields.Many2one('uom.uom', string='Satuan', default=lambda self: self.env.ref('uom.product_uom_unit', raise_if_not_found=False))
+ price_unit = fields.Float(string='Estimasi Harga Satuan')
+ notes = fields.Char(string='Keterangan')
diff --git a/addons/kosbar_purchase_finance/security/ir.model.access.csv b/addons/kosbar_purchase_finance/security/ir.model.access.csv
new file mode 100644
index 0000000..a51bb32
--- /dev/null
+++ b/addons/kosbar_purchase_finance/security/ir.model.access.csv
@@ -0,0 +1,4 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_purchase_request,access_purchase_request,model_kosbar_purchase_request,base.group_user,1,1,1,0
+access_purchase_request_line,access_purchase_request_line,model_kosbar_purchase_request_line,base.group_user,1,1,1,0
+access_purchase_order_finance,access_purchase_order_finance,model_purchase_order,kosbar_purchase_finance.group_finance,1,1,0,0
diff --git a/addons/kosbar_purchase_finance/security/res_groups.xml b/addons/kosbar_purchase_finance/security/res_groups.xml
new file mode 100644
index 0000000..c4115f2
--- /dev/null
+++ b/addons/kosbar_purchase_finance/security/res_groups.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ Finance / Accounting Approval
+
+
+
+
diff --git a/addons/kosbar_purchase_finance/views/purchase_order_views.xml b/addons/kosbar_purchase_finance/views/purchase_order_views.xml
new file mode 100644
index 0000000..7dc1db7
--- /dev/null
+++ b/addons/kosbar_purchase_finance/views/purchase_order_views.xml
@@ -0,0 +1,42 @@
+
+
+
+
+ purchase.order.form.finance
+ purchase.order
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ purchase.order.tree.finance
+ purchase.order
+
+
+
+
+
+
+
+
diff --git a/addons/kosbar_purchase_finance/views/purchase_request_views.xml b/addons/kosbar_purchase_finance/views/purchase_request_views.xml
new file mode 100644
index 0000000..5209e8a
--- /dev/null
+++ b/addons/kosbar_purchase_finance/views/purchase_request_views.xml
@@ -0,0 +1,85 @@
+
+
+
+
+ kosbar.purchase.request.tree
+ kosbar.purchase.request
+
+
+
+
+
+
+
+
+
+
+
+
+ kosbar.purchase.request.form
+ kosbar.purchase.request
+
+
+
+
+
+
+
+ Permintaan Barang
+ kosbar.purchase.request
+ list,form
+
+
+
+