summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindoteknik_custom/__manifest__.py2
-rwxr-xr-xindoteknik_custom/models/__init__.py1
-rw-r--r--indoteknik_custom/models/account_move.py16
-rw-r--r--indoteknik_custom/models/account_move_line.py65
-rwxr-xr-xindoteknik_custom/models/purchase_order.py14
-rwxr-xr-xindoteknik_custom/models/sale_order.py18
-rw-r--r--indoteknik_custom/models/shipment_group.py24
-rw-r--r--indoteknik_custom/models/stock_inventory.py44
-rw-r--r--indoteknik_custom/models/stock_picking.py13
-rw-r--r--indoteknik_custom/models/update_depreciation_move_wizard.py48
-rw-r--r--indoteknik_custom/report/purchase_report_internal.xml201
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv1
-rw-r--r--indoteknik_custom/views/account_move_line.xml12
-rw-r--r--indoteknik_custom/views/advance_payment_request.xml1
-rw-r--r--indoteknik_custom/views/approval_date_doc.xml2
-rw-r--r--indoteknik_custom/views/shipment_group.xml6
-rw-r--r--indoteknik_custom/views/stock_inventory.xml3
-rw-r--r--indoteknik_custom/views/stock_picking.xml1
-rw-r--r--indoteknik_custom/views/tukar_guling.xml24
-rw-r--r--indoteknik_custom/views/update_depreciation_move_wizard_view.xml35
20 files changed, 514 insertions, 17 deletions
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py
index dcb23344..66d59af2 100755
--- a/indoteknik_custom/__manifest__.py
+++ b/indoteknik_custom/__manifest__.py
@@ -169,6 +169,7 @@
'report/report_surat_piutang.xml',
'report/report_tutup_tempo.xml',
'report/purchase_report.xml',
+ 'report/purchase_report_internal.xml',
'views/vendor_sla.xml',
'views/coretax_faktur.xml',
'views/public_holiday.xml',
@@ -193,6 +194,7 @@
'views/domain_apo.xml',
'views/uom_uom.xml',
'views/commission_internal.xml',
+ 'views/update_depreciation_move_wizard_view.xml',
'views/keywords.xml'
],
'demo': [],
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py
index 328c76b0..a042750b 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -165,4 +165,5 @@ from . import partial_delivery
from . import domain_apo
from . import uom_uom
from . import commission_internal
+from . import update_depreciation_move_wizard
from . import keywords
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py
index e1360cfa..42467b78 100644
--- a/indoteknik_custom/models/account_move.py
+++ b/indoteknik_custom/models/account_move.py
@@ -587,6 +587,10 @@ class AccountMove(models.Model):
records = self.search([('id', 'in', self.ids)])
template = self.env.ref('indoteknik_custom.mail_template_efaktur_document')
+ ICP = self.env['ir.config_parameter'].sudo()
+ special_partner_ids = set(
+ int(x) for x in (ICP.get_param('efaktur.special_partner_ids') or '').split(',') if x
+ )
for record in records:
if record.invoice_payment_term_id.id == 26:
@@ -595,6 +599,18 @@ class AccountMove(models.Model):
'attachment_ids': [(4, attachment.id)]
}
template.send_mail(record.id, email_values=email_values, force_send=True)
+
+ elif record.partner_id.id in special_partner_ids:
+ attachment = self.generate_attachment(record)
+ email_list = [record.partner_id.email] if record.partner_id.email else []
+ if record.real_invoice_id and record.real_invoice_id.email:
+ email_list.append(record.real_invoice_id.email)
+
+ email_values = {
+ 'email_to': ",".join(set(email_list)),
+ 'attachment_ids': [(4, attachment.id)]
+ }
+ template.send_mail(record.id, email_values=email_values, force_send=True)
# @api.model
# def create(self, vals):
diff --git a/indoteknik_custom/models/account_move_line.py b/indoteknik_custom/models/account_move_line.py
index 7c95d4ef..5edea25f 100644
--- a/indoteknik_custom/models/account_move_line.py
+++ b/indoteknik_custom/models/account_move_line.py
@@ -1,5 +1,5 @@
from odoo import models, api, fields
-
+from odoo.exceptions import AccessError, UserError, ValidationError
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
@@ -9,6 +9,69 @@ class AccountMoveLine(models.Model):
analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Account')
line_no = fields.Integer('No', default=0)
+ def action_gl_reconcile(self):
+ lines = self
+
+ journal = self.env['account.journal'].search([
+ ('suspense_account_id', '=', lines[0].account_id.id)
+ ], limit=1)
+
+ if not journal:
+ raise UserError('Journal dengan suspense account ini tidak ditemukan!')
+
+ statement = self.env['account.bank.statement'].create({
+ 'journal_id': journal.id,
+ 'name': f'REKONSIL {journal.name} {lines[0].date.strftime("%d-%m-%Y")}',
+ 'company_id': self.env.company.id,
+ 'date': lines[0].date,
+ })
+
+ widget_vals = []
+ st_line_ids = []
+
+ for line in lines:
+ amount = line.debit - line.credit
+
+ st_line = self.env['account.bank.statement.line'].create({
+ 'statement_id': statement.id,
+ 'date': line.date or fields.Date.today(),
+ 'payment_ref': line.name,
+ 'partner_id': line.partner_id.id,
+ 'amount': amount,
+ 'ref': line.name,
+ })
+
+ st_line_ids.append(st_line.id)
+
+ widget_vals.append({
+ 'partner_id': st_line.partner_id.id,
+ 'counterpart_aml_dicts': [{
+ 'counterpart_aml_id': line.id,
+ 'debit': abs(amount) if amount < 0 else 0,
+ 'credit': abs(amount) if amount > 0 else 0,
+ 'name': line.name or '/',
+ }],
+ 'payment_aml_ids': [],
+ 'new_aml_dicts': [],
+ 'to_check': False,
+ })
+
+ statement.button_post()
+
+ self.env['account.reconciliation.widget'].process_bank_statement_line(
+ st_line_ids,
+ widget_vals
+ )
+ # statement.button_validate_or_action()
+
+ return {
+ 'effect': {
+ 'fadeout': 'slow',
+ 'message': 'Statement + Auto Reconcile sukses besar 😎🔥',
+ 'type': 'rainbow_man',
+ }
+ }
+
@api.onchange('account_id')
def _onchange_account_id(self):
for account in self:
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py
index 6c3e4185..b3ecca56 100755
--- a/indoteknik_custom/models/purchase_order.py
+++ b/indoteknik_custom/models/purchase_order.py
@@ -1080,13 +1080,13 @@ class PurchaseOrder(models.Model):
) % order.name)
def button_confirm(self):
- # if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan
- # if '/PJ/' in self.name:
- # price_change_detected = any(line.price_unit_before for line in self.order_line)
- # if price_change_detected:
- # if self.order_sales_match_line:
- # if self.total_percent_margin <= 15.0:
- # raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%")
+ if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan
+ if '/PJ/' in self.name:
+ price_change_detected = any(line.price_unit_before for line in self.order_line)
+ if price_change_detected:
+ if self.order_sales_match_line:
+ if self.total_percent_margin <= 15.0:
+ raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%")
self._check_assets_note()
# self._check_payment_term() # check payment term
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index a4bc2309..90cd5fa2 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -647,7 +647,7 @@ class SaleOrder(models.Model):
def _get_biteship_courier_codes(self):
return [
- 'gojek','grab','deliveree','lalamove','jne','tiki','ninja','lion','rara','sicepat','jnt','pos','idexpress','rpx','wahana','jdl','pos','anteraja','sap','paxel','borzo'
+ 'gojek','grab','deliveree','lalamove','jne','ninja','lion','rara','sicepat','jnt','pos','idexpress','rpx','wahana','jdl','anteraja','sap','paxel','borzo'
]
@api.onchange('carrier_id')
@@ -2316,7 +2316,7 @@ class SaleOrder(models.Model):
for order in self:
for line in order.order_line:
search_product = self.env['sale.order.line'].search(
- [('product_id', '=', line.product_id.id), ('order_id', '=', order.id)])
+ [('product_id', '=', line.product_id.id), ('order_id', '=', order.id), ('display_type', '=', False)])
if len(search_product) > 1:
raise UserError("Terdapat DUPLIKASI data pada Product {}".format(line.product_id.display_name))
@@ -2598,6 +2598,18 @@ class SaleOrder(models.Model):
else:
return False
+ def check_archived_product(self):
+ for order in self:
+ for line in order.order_line:
+ if line.product_id.active == False:
+ raise UserError("Terdapat Product yang sudah di Archive pada Product: {}".format(line.product_id.display_name))
+
+ def check_archived_uom(self):
+ for order in self:
+ for line in order.order_line:
+ if line.product_uom.active == False:
+ raise UserError("Terdapat UoM yang sudah di Archive pada UoM {} di Product {}".format(line.product_uom.name, line.product_id.display_name))
+
def action_confirm(self):
for order in self:
order._validate_delivery_amt()
@@ -2614,6 +2626,8 @@ class SaleOrder(models.Model):
order._validate_order()
order._validate_npwp()
order.order_line.validate_line()
+ order.check_archived_product()
+ order.check_archived_uom()
main_parent = order.partner_id.get_main_parent()
SYSTEM_UID = 25
diff --git a/indoteknik_custom/models/shipment_group.py b/indoteknik_custom/models/shipment_group.py
index 7203b566..ce4a9fdd 100644
--- a/indoteknik_custom/models/shipment_group.py
+++ b/indoteknik_custom/models/shipment_group.py
@@ -2,6 +2,7 @@ from odoo import models, api, fields
from odoo.exceptions import AccessError, UserError, ValidationError
from datetime import timedelta, date
import logging
+from markupsafe import escape as html_escape
_logger = logging.getLogger(__name__)
@@ -16,7 +17,21 @@ class ShipmentGroup(models.Model):
partner_id = fields.Many2one('res.partner', string='Customer')
carrier_id = fields.Many2one('delivery.carrier', string='Ekspedisi')
total_colly_line = fields.Float(string='Total Colly', compute='_compute_total_colly_line')
+ is_multi_partner = fields.Boolean(string='Is Multi Partner', compute='_compute_is_multi_partner')
+ partner_ids = fields.Many2many('res.partner', string='Customers', compute='_compute_partner_ids')
+ driver = fields.Many2one('res.users', string='Driver')
+ @api.depends('shipment_line.partner_id')
+ def _compute_partner_ids(self):
+ for rec in self:
+ rec.partner_ids = rec.shipment_line.mapped('partner_id').ids
+
+ @api.depends('shipment_line.partner_id')
+ def _compute_is_multi_partner(self):
+ for rec in self:
+ partners = rec.shipment_line.mapped('partner_id')
+ rec.is_multi_partner = len(partners) > 1
+
def sync_api_shipping(self):
for rec in self.shipment_line:
picking_names = [lines.picking_id.name for lines in self.shipment_line]
@@ -97,14 +112,14 @@ class ShipmentGroupLine(models.Model):
@api.onchange('picking_id')
def onchange_picking_id(self):
if self.picking_id:
- picking = self.env['stock.picking'].browse(self.picking_id.id)
+ picking = self.picking_id
if self.shipment_id.carrier_id and self.shipment_id.carrier_id != picking.carrier_id:
raise UserError('carrier must be same as shipment group')
-
+
if picking.total_mapping_koli == 0:
raise UserError(f'Picking {picking.name} tidak memiliki mapping koli')
-
+
self.partner_id = picking.partner_id
self.shipping_paid_by = picking.sale_id.shipping_paid_by
self.carrier_id = picking.carrier_id.id
@@ -115,6 +130,9 @@ class ShipmentGroupLine(models.Model):
self.sale_id = picking.sale_id
+ if self.shipment_id:
+ self.shipment_id._compute_is_multi_partner()
+
@api.model
def create(self, vals):
record = super(ShipmentGroupLine, self).create(vals)
diff --git a/indoteknik_custom/models/stock_inventory.py b/indoteknik_custom/models/stock_inventory.py
index 84eb5a17..efd52e5c 100644
--- a/indoteknik_custom/models/stock_inventory.py
+++ b/indoteknik_custom/models/stock_inventory.py
@@ -17,6 +17,35 @@ class StockInventory(models.Model):
('out', 'Adjusment Out'),
], string='Adjusments Type', required=True)
+ approval_state = fields.Selection([
+ ('logistic', 'Logistic'),
+ ('accounting', 'Accounting'),
+ ('approved', 'Approved'),
+ ], tracking=True, readonly=True)
+
+ def action_validate(self):
+ if self.adjusment_type == 'out':
+
+ if self.approval_state != 'approved':
+
+ if self.approval_state == 'logistic':
+ if not self.env.user.has_group('indoteknik_custom.group_role_logistic'):
+ raise UserError("Adjustment Out harus dilakukan oleh Logistic")
+ self.approval_state = 'accounting'
+ return True
+
+ elif self.approval_state == 'accounting':
+ if not self.env.user.has_group('indoteknik_custom.group_role_fat'):
+ raise UserError("Adjustment Out harus dilakukan oleh Accounting")
+ self.approval_state = 'approved'
+ return super(StockInventory, self).action_validate()
+
+ else:
+ raise UserError("Adjustment Out harus melalui approval terlebih dahulu.")
+
+ return super(StockInventory, self).action_validate()
+
+
def _generate_number_stock_inventory(self):
"""Men-generate nomor untuk semua stock inventory yang belum memiliki number."""
stock_records = self.env['stock.inventory'].search([('number', '=', False)], order='id asc')
@@ -53,13 +82,19 @@ class StockInventory(models.Model):
return "00001" # Jika belum ada data, mulai dari 00001
def action_start(self):
- if self.env.user.id not in [21, 17, 571, 28]:
- raise UserError("Hanya Rafly, Denise, Iqmal, dan Stephan yang bisa start inventory")
+ if self.env.user.id not in [21, 17, 571, 28, 25]:
+ raise UserError("Hanya Rafly, Denise, Iqmal, dan Stephan yang bisa start inventory")
return super(StockInventory, self).action_start()
@api.model
def create(self, vals):
"""Pastikan nomor hanya dibuat saat penyimpanan."""
+
+ if vals.get('adjusment_type') == 'in':
+ vals['approval_state'] = False
+ elif vals.get('adjusment_type') == 'out':
+ vals['approval_state'] = 'logistic'
+
if 'adjusment_type' in vals and not vals.get('number'):
vals['number'] = False # Jangan buat number otomatis dulu
@@ -69,12 +104,17 @@ class StockInventory(models.Model):
self._assign_number(order) # Generate number setelah save
return order
+
def write(self, vals):
"""Jika adjusment_type diubah, generate ulang nomor."""
res = super(StockInventory, self).write(vals)
if 'adjusment_type' in vals:
for record in self:
+ if record.adjusment_type == 'in':
+ record.approval_state = False
+ elif record.adjusment_type == 'out' and record.approval_state == False:
+ record.approval_state = 'logistic'
self._assign_number(record)
return res
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index 2465fa96..065b1484 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -203,6 +203,16 @@ class StockPicking(models.Model):
is_so_fiktif = fields.Boolean('SO Fiktif?', compute='_compute_is_so_fiktif', tracking=3)
payment_term = fields.Char('Payment Term', compute='_get_partner_payment_term')
is_rev_tg = fields.Boolean('Administrasi')
+ shipment_group_id = fields.Many2one('shipment.group', string='Shipment Group', compute='_compute_shipment_group_id')
+
+ @api.depends('shipment_group_id')
+ def _compute_shipment_group_id(self):
+ for record in self:
+ shipment_line = self.env['shipment.group.line'].search([('picking_id', '=', record.id)], limit=1)
+ if shipment_line:
+ record.shipment_group_id = shipment_line.shipment_id.id
+ else:
+ record.shipment_group_id = False
@api.depends('sale_id.payment_term_id')
def _get_partner_payment_term(self):
@@ -1387,7 +1397,8 @@ class StockPicking(models.Model):
])
if quant:
- return quant.quantity
+ return sum(quant.mapped('quantity'))
+ # return quant.quantity
return 0
diff --git a/indoteknik_custom/models/update_depreciation_move_wizard.py b/indoteknik_custom/models/update_depreciation_move_wizard.py
new file mode 100644
index 00000000..7d465f1d
--- /dev/null
+++ b/indoteknik_custom/models/update_depreciation_move_wizard.py
@@ -0,0 +1,48 @@
+from odoo import models, fields, api
+from odoo.exceptions import UserError
+
+class UpdateDepreciationMoveWizard(models.TransientModel):
+ _name = 'update.depreciation.move.wizard'
+ _description = 'Wizard untuk Update Move Check Depreciation Line'
+
+ target_date = fields.Date(string="Tanggal Depresiasi", required=True)
+
+ # def action_update_move_check(self):
+ # lines = self.env['account.asset.depreciation.line'].search([
+ # ('depreciation_date', '=', self.target_date),
+ # ])
+ # if not lines:
+ # raise UserError("Tidak ada baris depresiasi dengan tanggal tersebut.")
+
+ # updated_count = 0
+ # for line in lines:
+ # if not line.move_check:
+ # line.move_check = True
+ # line.move_posted_check = True
+ # updated_count += 1
+
+ # return {
+ # 'type': 'ir.actions.client',
+ # 'tag': 'display_notification',
+ # 'params': {
+ # 'title': 'Update Selesai',
+ # 'message': f'{updated_count} baris berhasil di-update.',
+ # 'type': 'success',
+ # 'sticky': False,
+ # }
+ # }
+
+ def action_update_move_check(self):
+ assets = self.env['account.asset.asset']
+ assets.compute_generated_entries(self.target_date)
+
+ return {
+ 'type': 'ir.actions.client',
+ 'tag': 'display_notification',
+ 'params': {
+ 'title': 'Update Selesai',
+ 'message': 'Depresiasi berhasil di-update.',
+ 'type': 'success',
+ 'sticky': False,
+ }
+ } \ No newline at end of file
diff --git a/indoteknik_custom/report/purchase_report_internal.xml b/indoteknik_custom/report/purchase_report_internal.xml
new file mode 100644
index 00000000..7df847de
--- /dev/null
+++ b/indoteknik_custom/report/purchase_report_internal.xml
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <!-- Report Action -->
+ <record id="action_report_purchaseorder_internal" model="ir.actions.report">
+ <field name="name">Purchase Order (Internal)</field>
+ <field name="model">purchase.order</field>
+ <field name="report_type">qweb-pdf</field>
+ <field name="report_name">indoteknik_custom.report_purchaseorder_internal</field>
+ <field name="report_file">indoteknik_custom.report_purchaseorder_internal</field>
+ <field name="print_report_name">
+ ('%s - %s' % (object.name, object.partner_id.name))
+ </field>
+ <field name="binding_model_id" ref="purchase.model_purchase_order"/>
+ <field name="binding_type">report</field>
+ </record>
+ </data>
+
+ <!-- Wrapper Template -->
+ <template id="report_purchaseorder_internal">
+ <t t-call="web.html_container">
+ <t t-foreach="docs" t-as="doc">
+ <t t-call="indoteknik_custom.report_purchaseorder_internal_document" t-lang="doc.partner_id.lang"/>
+ </t>
+ </t>
+ </template>
+
+ <template id="report_purchaseorder_internal_document">
+ <t t-call="web.html_container">
+ <t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)" />
+
+ <!-- HEADER -->
+ <div class="header">
+ <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2498521"
+ style="width:100%; display:block;"/>
+ </div>
+
+ <!-- PAGE CONTENT -->
+ <div class="article" style="margin: 0 1.5cm 0 1.5cm; font-family:Arial, sans-serif; font-size:14px; color:#333;">
+
+ <!-- TITLE -->
+ <h2 style="text-align:center; margin:8px 0 0 0; color:#d32f2f; font-weight:800; letter-spacing:1px;">
+ PURCHASE ORDER
+ </h2>
+ <h4 style="text-align:center; margin:4px 0 20px 0; font-weight:normal; color:#555;">
+ No. <span t-field="doc.name"/>
+ </h4>
+
+ <!-- TOP INFO -->
+ <table style="width:100%; margin-bottom:20px; border-radius:8px; box-shadow:0 1px 4px rgba(0,0,0,0.1); overflow:hidden; border:1px solid #ddd;">
+ <tr style="background:#fafafa;">
+ <td style="padding:10px 12px;"><strong>Term Of Payment:</strong> <span t-field="doc.payment_term_id.name"/></td>
+ <td style="padding:10px 12px;"><strong>Order Date:</strong> <span t-field="doc.date_order" t-options='{"widget": "date"}'/></td>
+ <td style="padding:10px 12px;"><strong>Responsible:</strong> <span t-field="doc.user_id"/></td>
+ </tr>
+ </table>
+
+ <!-- VENDOR & DELIVERY -->
+ <table style="width:100%; margin-bottom:24px; border-spacing:16px 0;">
+ <tr>
+ <td style="width:50%; border:1px solid #ccc; border-radius:8px; padding:10px; background:#fcfcfc; vertical-align:top;">
+ <strong style="color:#d32f2f;">Alamat Pengiriman</strong><br/>
+ PT. Indoteknik Dotcom Gemilang<br/>
+ <t t-if="doc.overseas_po == True">
+ JALAN BANDENGAN UTARA 85A NO.8-9 RT. 003<br/>
+ RW. 016, PENJARINGAN, PENJARINGAN, KOTA<br/>
+ ADM. JAKARTA UTARA, DKI JAKARTA
+ </t>
+ <t t-else="">
+ Jl. Bandengan Utara Komp A &amp; B RT.<br/>
+ Penjaringan, Kec. Penjaringan, Jakarta<br/>
+ (BELAKANG INDOMARET)
+ </t>
+ <br/>
+ Daerah Khusus Ibukota Jakarta 14440
+ </td>
+ <td style="width:50%; border:1px solid #ccc; border-radius:8px; padding:10px; background:#fcfcfc; vertical-align:top;">
+ <strong style="color:#d32f2f;">Nama Vendor</strong><br/>
+ <span t-field="doc.partner_id.name"/><br/>
+ <span t-field="doc.partner_id.street"/><br/>
+ <span t-field="doc.partner_id.city"/> - <span t-field="doc.partner_id.zip"/>
+ </td>
+ </tr>
+ </table>
+
+ <!-- ORDER LINES -->
+ <table style="border-collapse:collapse; width:100%; margin-top:16px; font-size:14px;">
+ <tbody>
+ <!-- HEADER -->
+ <tr style="background:#e53935; color:white;">
+ <th style="border:1px solid #ccc; padding:8px; text-align:left;">No. &amp; Description</th>
+ <th style="border:1px solid #ccc; padding:8px; text-align:left;">Image</th>
+ <th style="border:1px solid #ccc; padding:8px; text-align:center;">Quantity</th>
+ <th style="border:1px solid #ccc; padding:8px; text-align:center;">Unit Price</th>
+ <th style="border:1px solid #ccc; padding:8px; text-align:center;">Taxes</th>
+ <th style="border:1px solid #ccc; padding:8px; text-align:center;">Subtotal</th>
+ </tr>
+
+ <!-- ISI ORDER LINE -->
+ <t t-foreach="doc.order_line" t-as="line" t-index="line_index">
+ <tr t-attf-style="background-color: #{ '#fafafa' if line_index % 2 == 0 else 'white' };">
+
+ <!-- NO & DESCRIPTION + IMAGE -->
+ <td style="border:1px solid #ccc; padding: 6px; display:flex; align-items:center; gap:10px;">
+ <!-- TEKS -->
+ <div style="display:flex; flex-direction:column; flex:1;">
+ <span style="font-weight:bold; margin-bottom:2px;">
+ <t t-esc="line_index + 1"/>.
+ <t t-if="line.product_id.id in [114360, 595346, 610166, 420315]">
+ <t t-esc="line.name"/>
+ </t>
+ <t t-else="">
+ <t t-esc="line.product_id.display_name"/>
+ </t>
+ </span>
+ </div>
+
+ </td>
+
+ <td style="border:1px solid #ccc; padding:6px; text-align:center;">
+ <t t-if="line.image_small">
+ <img t-att-src="image_data_uri(line.image_small)"
+ style="width:100px; height:100px; object-fit:contain; border:1px solid #ddd; border-radius:6px; background:#fff;"/>
+ </t>
+ </td>
+ <!-- QTY -->
+ <td style="border:1px solid #ccc; padding:6px; text-align:center;">
+ <span t-field="line.product_qty"/> <span t-field="line.product_uom"/>
+ </td>
+
+ <!-- UNIT PRICE -->
+ <td style="border:1px solid #ccc; padding:6px; text-align:center;">
+ <span t-field="line.price_unit"/>
+ </td>
+
+ <!-- TAXES -->
+ <td style="border:1px solid #ccc; padding:6px; text-align:center;">
+ <span t-esc="', '.join(map(lambda x: (x.description or x.name), line.taxes_id))"/>
+ </td>
+
+ <!-- SUBTOTAL -->
+ <td style="border:1px solid #ccc; padding:6px; text-align:right; font-weight:bold;">
+ <span t-field="line.price_subtotal"/>
+ </td>
+ </tr>
+
+ <!-- WEBSITE DESCRIPTION -->
+ <t t-if="line.show_description == True">
+ <tr t-attf-style="background-color: #{ '#fef5f5' if line_index % 2 == 0 else '#fffafa' }; ">
+ <td colspan="6" style="padding: 10px 14px; font-size:10px; line-height:1.3; font-style:italic; color:#555; border-left:1px solid #ccc; border-right:1px solid #ccc; border-bottom:1px solid #ccc;">
+ <div t-raw="line.product_id.website_description"/>
+ </td>
+ </tr>
+ </t>
+ </t>
+ </tbody>
+ </table>
+
+
+ <!-- TOTALS -->
+ <table style="margin-top:24px; margin-left:auto; width:40%; font-size:14px; border:1px solid #ddd; border-radius:6px; box-shadow:0 1px 3px rgba(0,0,0,0.08);">
+ <tr style="background:#fafafa;">
+ <td style="padding:8px;"><strong>Subtotal</strong></td>
+ <td style="text-align:right; padding:8px;"><span t-field="doc.amount_untaxed"/></td>
+ </tr>
+ <tr>
+ <td style="padding:8px;">Taxes</td>
+ <td style="text-align:right; padding:8px;"><span t-field="doc.amount_tax"/></td>
+ </tr>
+ <tr style="background:#fbe9e7; font-weight:bold; color:#d32f2f;">
+ <td style="padding:8px;">Total</td>
+ <td style="text-align:right; padding:8px;"><span t-field="doc.amount_total"/></td>
+ </tr>
+ <tr>
+ <td style="padding:8px;">Margin PO %</td>
+ <td style="text-align:right; padding:8px;"><span t-field="doc.total_percent_margin"/></td>
+ </tr>
+ <tr>
+ <td style="padding:8px;">Margin SO %</td>
+ <td style="text-align:right; padding:8px;"><span t-field="doc.total_so_percent_margin"/></td>
+ </tr>
+ </table>
+
+ <!-- NOTES -->
+ <div style="margin-top:24px; padding:12px; border-top:1px solid #ddd; font-style:italic; color:#555;">
+ <p t-field="doc.notes"/>
+ </div>
+ </div>
+
+ <!-- STATIC FOOTER -->
+ <div class="footer">
+ <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2859765"
+ style="width:100%; display:block;"/>
+ </div>
+
+ </t>
+ </template>
+
+
+
+</odoo>
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index 7f553ddc..4ffefc68 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -215,4 +215,5 @@ access_surat_piutang_user,surat.piutang user,model_surat_piutang,,1,1,1,1
access_surat_piutang_line_user,surat.piutang.line user,model_surat_piutang_line,,1,1,1,1
access_sj_tele,access.sj.tele,model_sj_tele,base.group_system,1,1,1,1
access_stock_picking_sj_document,stock.picking.sj.document,model_stock_picking_sj_document,base.group_user,1,1,1,1
+access_update_depreciation_move_wizard,access.update.depreciation.move.wizard,model_update_depreciation_move_wizard,,1,1,1,1
access_keywords,keywords,model_keywords,base.group_user,1,1,1,1
diff --git a/indoteknik_custom/views/account_move_line.xml b/indoteknik_custom/views/account_move_line.xml
index cb24a0f0..838596c8 100644
--- a/indoteknik_custom/views/account_move_line.xml
+++ b/indoteknik_custom/views/account_move_line.xml
@@ -22,4 +22,16 @@
</field>
</record>
</data>
+ <data>
+ <record id="action_gl_reconcile_server" model="ir.actions.server">
+ <field name="name">Reconcile Selected</field>
+ <field name="model_id" ref="account.model_account_move_line"/>
+ <field name="binding_model_id" ref="account.model_account_move_line"/>
+ <field name="binding_view_types">list</field>
+ <field name="state">code</field>
+ <field name="code">
+ action = records.action_gl_reconcile()
+ </field>
+ </record>
+ </data>
</odoo>
diff --git a/indoteknik_custom/views/advance_payment_request.xml b/indoteknik_custom/views/advance_payment_request.xml
index 7f422aa9..340e0caf 100644
--- a/indoteknik_custom/views/advance_payment_request.xml
+++ b/indoteknik_custom/views/advance_payment_request.xml
@@ -236,6 +236,7 @@
<filter string="PUM" name="filter_pum" domain="[('type_request','=','pum')]"/>
<filter string="Reimburse" name="filter_reimburse" domain="[('type_request','=','reimburse')]"/>
<separator/>
+ <filter string="Cancelled" name="filter_cancelled" domain="[('status','=','cancel')]"/>
<filter string="Waiting for Approval" name="filter_waiting_approval" domain="[('status','in',['pengajuan1','pengajuan2','pengajuan3'])]"/>
<filter string="Approved" name="filter_approved" domain="[('status','=','approved')]"/>
<separator/>
diff --git a/indoteknik_custom/views/approval_date_doc.xml b/indoteknik_custom/views/approval_date_doc.xml
index 3d597aa8..a3aae3b4 100644
--- a/indoteknik_custom/views/approval_date_doc.xml
+++ b/indoteknik_custom/views/approval_date_doc.xml
@@ -14,6 +14,7 @@
<field name="approve_date"/>
<field name="approve_by"/>
<field name="create_uid"/>
+ <field name="create_date"/>
</tree>
</field>
</record>
@@ -46,6 +47,7 @@
<field name="approve_date"/>
<field name="approve_by"/>
<field name="create_uid"/>
+ <field name="create_date"/>
<field name="note" attrs="{'invisible': [('state', '!=', 'cancel')]}"/>
<field name="state" readonly="1"/>
</group>
diff --git a/indoteknik_custom/views/shipment_group.xml b/indoteknik_custom/views/shipment_group.xml
index c3f79bda..e348867c 100644
--- a/indoteknik_custom/views/shipment_group.xml
+++ b/indoteknik_custom/views/shipment_group.xml
@@ -7,6 +7,7 @@
<tree default_order="create_date desc">
<field name="number"/>
<field name="partner_id"/>
+ <field name="partner_ids" widget="many2many_tags" optional="hide"/>
<field name="carrier_id"/>
<field name="total_colly_line"/>
</tree>
@@ -42,9 +43,12 @@
<group>
<group>
<field name="number" readonly="1"/>
+ <field name="is_multi_partner" readonly="1"/>
</group>
<group>
- <field name="partner_id" readonly="1"/>
+ <field name="partner_id" readonly="1" attrs="{'invisible': [('is_multi_partner', '=', True)]}"/>
+ <field name="partner_ids" readonly="1" widget="many2many_tags" attrs="{'invisible': [('is_multi_partner', '=', False)]}"/>
+ <field name="driver" attrs="{'invisible': [('carrier_id', '!=', 1)]}"/>
<field name="carrier_id" readonly="1"/>
<field name="total_colly_line" readonly="1"/>
</group>
diff --git a/indoteknik_custom/views/stock_inventory.xml b/indoteknik_custom/views/stock_inventory.xml
index db85f05c..ab1b6eec 100644
--- a/indoteknik_custom/views/stock_inventory.xml
+++ b/indoteknik_custom/views/stock_inventory.xml
@@ -9,6 +9,7 @@
<xpath expr="//field[@name='location_ids']" position="after">
<field name="number" readonly="1"/>
<field name="adjusment_type" />
+ <field name="approval_state" />
</xpath>
</field>
</record>
@@ -21,6 +22,8 @@
<field name="arch" type="xml">
<xpath expr="//field[@name='date']" position="after">
<field name="number"/>
+ <field name="adjusment_type" />
+ <field name="approval_state"/>
</xpath>
</field>
</record>
diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml
index 9aa0581c..9cd63e25 100644
--- a/indoteknik_custom/views/stock_picking.xml
+++ b/indoteknik_custom/views/stock_picking.xml
@@ -245,6 +245,7 @@
<field name="responsible"/>
<field name="carrier_id"
attrs="{'invisible': [('select_shipping_option_so', '=', 'biteship')]}"/>
+ <field name="shipment_group_id"/>
<field name="biteship_id" invisible="1"/>
<field name="out_code" attrs="{'invisible': [['out_code', '=', False]]}"/>
<field name="picking_code" attrs="{'invisible': [['picking_code', '=', False]]}"/>
diff --git a/indoteknik_custom/views/tukar_guling.xml b/indoteknik_custom/views/tukar_guling.xml
index 8cfb5680..609dea15 100644
--- a/indoteknik_custom/views/tukar_guling.xml
+++ b/indoteknik_custom/views/tukar_guling.xml
@@ -133,5 +133,29 @@
</form>
</field>
</record>
+ <record id="view_tukar_guling_filter" model="ir.ui.view">
+ <field name="name">tukar.guling.filter</field>
+ <field name="model">tukar.guling</field>
+ <field name="arch" type="xml">
+ <search string="Tukar Guling">
+ <field name="name" string="No. Dokumen"/>
+ <field name="partner_id" string="Customer"/>
+ <field name="origin" string="SO Number"/>
+ <field name="operations" string="Operations"/>
+ <!-- <filter string="Pengajuan Saya" name="my_tukar_guling" domain="[('create_uid', '=', uid)]"/> -->
+ <separator/>
+ <filter string="Tukar Guling" name="tukar_guling" domain="[('return_type', '=', 'tukar_guling')]"/>
+ <filter string="Return SO" name="return_so" domain="[('return_type', '=', 'retur_so')]"/>
+ <separator/>
+ <filter string="Approval Sales" name="approval_sales" domain="[('state', '=', 'approval_sales')]"/>
+ <filter string="Approval Logistic" name="approval_logistic" domain="[('state', '=', 'approval_logistic')]"/>
+ <filter string="Approval Finance" name="approval_finance" domain="[('state', '=', 'approval_finance')]"/>
+ <filter string="Approved" name="approved" domain="[('state', '=', 'approved')]"/>
+ <separator/>
+ <filter string="Done" name="done" domain="[('state', '=', 'done')]"/>
+ <filter string="Cancelled" name="cancel" domain="[('state', '=', 'cancel')]"/>
+ </search>
+ </field>
+ </record>
</data>
</odoo>
diff --git a/indoteknik_custom/views/update_depreciation_move_wizard_view.xml b/indoteknik_custom/views/update_depreciation_move_wizard_view.xml
new file mode 100644
index 00000000..ff128a71
--- /dev/null
+++ b/indoteknik_custom/views/update_depreciation_move_wizard_view.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <record id="view_update_depreciation_move_wizard_form" model="ir.ui.view">
+ <field name="name">update.depreciation.move.wizard.form</field>
+ <field name="model">update.depreciation.move.wizard</field>
+ <field name="arch" type="xml">
+ <form string="Update Move Check">
+ <group>
+ <field name="target_date"/>
+ </group>
+ <footer>
+ <button string="Update" type="object" name="action_update_move_check" class="btn-primary"/>
+ <button string="Batal" special="cancel" class="btn-secondary"/>
+ </footer>
+ </form>
+ </field>
+ </record>
+
+ <record id="update_depreciation_move_wizard_action" model="ir.actions.act_window">
+ <field name="name">Update Depreciation Asset</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">update.depreciation.move.wizard</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ </record>
+
+ <menuitem
+ id="menu_update_depreciation_move_wizard"
+ name="Update Depreciation Asset"
+ parent="account.menu_finance_entries_management"
+ sequence="4"
+ action="update_depreciation_move_wizard_action"
+ />
+</odoo>
+ \ No newline at end of file