summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indoteknik_custom/models/approval_payment_term.py9
-rw-r--r--indoteknik_custom/models/dunning_run.py3
-rw-r--r--indoteknik_custom/models/logbook_sj.py5
-rw-r--r--indoteknik_custom/models/manufacturing.py22
-rwxr-xr-xindoteknik_custom/models/purchase_order.py21
-rwxr-xr-xindoteknik_custom/models/purchase_order_line.py1
-rw-r--r--indoteknik_custom/models/report_logbook_sj.py58
-rwxr-xr-xindoteknik_custom/models/sale_order.py115
-rw-r--r--indoteknik_custom/models/sale_order_line.py6
-rw-r--r--indoteknik_custom/models/tukar_guling.py28
-rw-r--r--indoteknik_custom/models/tukar_guling_po.py24
-rw-r--r--indoteknik_custom/report/purchase_report.xml213
-rw-r--r--indoteknik_custom/views/approval_payment_term.xml2
-rw-r--r--indoteknik_custom/views/dunning_run.xml5
-rwxr-xr-xindoteknik_custom/views/purchase_order.xml11
-rw-r--r--indoteknik_custom/views/report_logbook_sj.xml2
-rw-r--r--indoteknik_custom/views/res_partner.xml10
-rwxr-xr-xindoteknik_custom/views/sale_order.xml12
-rw-r--r--indoteknik_custom/views/tukar_guling_po.xml2
19 files changed, 299 insertions, 250 deletions
diff --git a/indoteknik_custom/models/approval_payment_term.py b/indoteknik_custom/models/approval_payment_term.py
index 08d91738..449bd90b 100644
--- a/indoteknik_custom/models/approval_payment_term.py
+++ b/indoteknik_custom/models/approval_payment_term.py
@@ -69,8 +69,8 @@ class ApprovalPaymentTerm(models.Model):
return res
def _track_changes_for_user_688(self, vals, old_values_dict):
- if self.env.user.id != 688:
- return
+ # if self.env.user.id != 688:
+ # return
tracked_fields = {"blocking_stage", "warning_stage", "property_payment_term_id"}
@@ -106,7 +106,8 @@ class ApprovalPaymentTerm(models.Model):
if changes:
timestamp = fields.Datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- rec.change_log_688 = f"{timestamp} - Perubahan oleh Widya:\n" + "\n".join(changes)
+ user = self.env.user
+ rec.change_log_688 = f"{timestamp} - Perubahan oleh {user.name}:\n" + "\n".join(changes)
@staticmethod
@@ -172,7 +173,7 @@ class ApprovalPaymentTerm(models.Model):
'warning_stage': self.warning_stage,
'active_limit': self.active_limit,
'property_payment_term_id': self.property_payment_term_id.id,
- 'is_locked_cbd': False,
+ 'is_cbd_locked': False,
})
self.approve_date = datetime.utcnow()
self.state = 'approved'
diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py
index 5a6aebac..9feea1d1 100644
--- a/indoteknik_custom/models/dunning_run.py
+++ b/indoteknik_custom/models/dunning_run.py
@@ -1,6 +1,6 @@
from odoo import models, api, fields
from odoo.exceptions import AccessError, UserError, ValidationError
-from datetime import timedelta
+from datetime import timedelta, date
import logging
@@ -149,4 +149,5 @@ class DunningRunLine(models.Model):
total_amt = fields.Float(string='Total Amount')
open_amt = fields.Float(string='Open Amount')
due_date = fields.Date(string='Due Date')
+ payment_term = fields.Many2one('account.payment.term', related='invoice_id.invoice_payment_term_id', string='Payment Term')
diff --git a/indoteknik_custom/models/logbook_sj.py b/indoteknik_custom/models/logbook_sj.py
index 75b2622f..0cda9c8b 100644
--- a/indoteknik_custom/models/logbook_sj.py
+++ b/indoteknik_custom/models/logbook_sj.py
@@ -24,6 +24,7 @@ class LogbookSJ(models.TransientModel):
}
report_logbook = self.env['report.logbook.sj'].create([parameters_header])
+ seq=1
for line in logbook_line:
picking = self.env['stock.picking'].search([('picking_code', '=', line.name)], limit=1)
if not picking:
@@ -43,9 +44,11 @@ class LogbookSJ(models.TransientModel):
'tracking_no': stock.delivery_tracking_no,
'partner_id': parent_id,
'report_logbook_sj_id': report_logbook.id,
- 'note': line.note
+ 'note': line.note,
+ 'line_num': seq
}
self.env['report.logbook.sj.line'].create([data])
+ seq += 1
report_logbook_ids.append(report_logbook.id)
line.unlink()
diff --git a/indoteknik_custom/models/manufacturing.py b/indoteknik_custom/models/manufacturing.py
index aea01362..f986fd4f 100644
--- a/indoteknik_custom/models/manufacturing.py
+++ b/indoteknik_custom/models/manufacturing.py
@@ -4,54 +4,56 @@ import logging
_logger = logging.getLogger(__name__)
+
class Manufacturing(models.Model):
_inherit = 'mrp.production'
unbuild_counter = fields.Integer(string='Unbuild Counter', default=0, help='For restrict unbuild more than once')
-
+
def action_confirm(self):
if self._name != 'mrp.production':
return super(Manufacturing, self).action_confirm()
if not self.env.user.is_purchasing_manager:
raise UserError("Hanya bisa di confirm oleh Purchasing Manager")
-
+
# if self.location_src_id.id != 75:
# raise UserError('Component Location hanya bisa di AS/Stock')
# elif self.location_dest_id.id != 75:
# raise UserError('Finished Product Location hanya bisa di AS/Stock')
-
+
result = super(Manufacturing, self).action_confirm()
return result
-
+
def button_mark_done(self):
if self._name != 'mrp.production':
return super(Manufacturing, self).button_mark_done()
# Check product category
if self.product_id.categ_id.name != 'Finish Good':
raise UserError('Tidak bisa di complete karna product category bukan Unit / Finish Good')
-
+
if self.sale_order and self.sale_order.state != 'sale':
raise UserError(
('Tidak bisa Mark as Done.\nSales Order "%s" (Nomor: %s) belum dikonfirmasi.')
% (self.sale_order.partner_id.name, self.sale_order.name)
)
-
+
for line in self.move_raw_ids:
# if line.quantity_done > 0 and line.quantity_done != self.product_uom_qty:
# raise UserError('Qty Consume per Line tidak sama dengan Qty to Produce')
if line.forecast_availability != line.product_uom_qty:
- raise UserError('Qty Reserved belum sesuai dengan yang seharusnya, product: %s' % line.product_id.display_name)
+ raise UserError(
+ 'Qty Reserved belum sesuai dengan yang seharusnya, product: %s' % line.product_id.display_name)
result = super(Manufacturing, self).button_mark_done()
return result
-
+
def button_unbuild(self):
if self._name != 'mrp.production':
return super(Manufacturing, self).button_unbuild()
-
+
if self.unbuild_counter >= 1:
raise UserError('Tidak bisa unbuild lebih dari 1 kali')
-
+
self.unbuild_counter = self.unbuild_counter + 1
result = super(Manufacturing, self).button_unbuild()
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py
index 18811b85..e7e5c382 100755
--- a/indoteknik_custom/models/purchase_order.py
+++ b/indoteknik_custom/models/purchase_order.py
@@ -6,6 +6,7 @@ import logging
from pytz import timezone, utc
import io
import base64
+from odoo.tools import lazy_property
try:
from odoo.tools.misc import xlsxwriter
except ImportError:
@@ -115,6 +116,19 @@ class PurchaseOrder(models.Model):
compute='_compute_complete_bu_in_count'
)
+ show_description = fields.Boolean(
+ string='Show Description'
+ )
+
+ @api.onchange('show_description')
+ def onchange_show_description(self):
+ if self.show_description == True:
+ for line in self.order_line:
+ line.show_description = True
+ else:
+ for line in self.order_line:
+ line.show_description = False
+
def _compute_complete_bu_in_count(self):
for order in self:
if order.state not in ['done', 'cancel']:
@@ -137,7 +151,7 @@ class PurchaseOrder(models.Model):
def _compute_date_planned(self):
""" date_planned = the earliest date_planned across all order lines. """
for order in self:
- order.date_planned = False
+ order.date_planned = order.date_planned
@api.constrains('date_planned')
def constrains_date_planned(self):
@@ -1066,8 +1080,11 @@ class PurchaseOrder(models.Model):
# sticky=True
# )
+ has_bom = self.product_bom_id.id
+ has_manufacturing = self.manufacturing_id.id
+
if not self.from_apo:
- if not self.matches_so and not self.env.user.is_purchasing_manager and not self.env.user.is_leader:
+ if not self.matches_so and not self.env.user.is_purchasing_manager and not self.env.user.is_leader and not has_bom and not has_manufacturing:
raise UserError("Tidak ada link dengan SO, harus di confirm oleh Purchasing Manager")
send_email = False
diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py
index 315795d5..a3c3a33b 100755
--- a/indoteknik_custom/models/purchase_order_line.py
+++ b/indoteknik_custom/models/purchase_order_line.py
@@ -50,6 +50,7 @@ class PurchaseOrderLine(models.Model):
cost_service_per_item = fields.Float(string='Biaya Jasa Per Item', compute='_compute_doc_delivery_amt')
contribution_cost_service = fields.Float(string='Contribution Cost Service', compute='_compute_doc_delivery_amt')
ending_price = fields.Float(string='Ending Price', compute='_compute_doc_delivery_amt')
+ show_description = fields.Boolean(string='Show Description', help="Show Description when print po", default=True)
def _compute_doc_delivery_amt(self):
for line in self:
diff --git a/indoteknik_custom/models/report_logbook_sj.py b/indoteknik_custom/models/report_logbook_sj.py
index 17119c12..66edbf99 100644
--- a/indoteknik_custom/models/report_logbook_sj.py
+++ b/indoteknik_custom/models/report_logbook_sj.py
@@ -1,3 +1,5 @@
+from operator import index
+
from odoo import models, fields, api
from odoo.exceptions import UserError
from pytz import timezone
@@ -60,9 +62,30 @@ class ReportLogbookSJ(models.Model):
self.state = 'terima_semua'
else:
raise UserError('Hanya Accounting yang bisa Approve')
-
+
+
+ def write(self, vals):
+ res = super(ReportLogbookSJ, self).write(vals)
+ if 'report_logbook_sj_line' in vals or any(f in vals for f in ()):
+ self._resequence_lines()
+ return res
+
+ def _resequence_lines(self):
+ for rec in self:
+ lines = rec.report_logbook_sj_line.sorted(key=lambda l: (l.line_num or 0, l.id))
+ for idx, line in enumerate(lines, start=1):
+ if line.line_num != idx:
+ line.line_num = idx
+
+ @api.onchange('report_logbook_sj_line')
+ def _onchange_report_logbook_sj_line(self):
+ self._resequence_lines()
+
+from odoo import models, fields, api
+
class ReportLogbookSJLine(models.Model):
_name = 'report.logbook.sj.line'
+ _order = 'sequence, id' # urut default di UI & ORM (drag pakai sequence)
name = fields.Char(string='SJ Number')
driver_id = fields.Many2one(comodel_name='res.users', string='Driver')
@@ -70,10 +93,41 @@ class ReportLogbookSJLine(models.Model):
arrival_date = fields.Char(string='Arrival Date')
carrier_id = fields.Many2one('delivery.carrier', string='Shipping Method')
tracking_no = fields.Char(string='Tracking No')
- logbook_sj_id = fields.Many2one('report.logbook.sj', string='Logbook SJ') # Corrected model name
+
+ # NOTE: field ini duplikat relasi; pakai salah satu saja.
+ # kamu boleh hapus logbook_sj_id kalau tidak dipakai di tempat lain.
+ logbook_sj_id = fields.Many2one('report.logbook.sj', string='Logbook SJ')
+
partner_id = fields.Many2one('res.partner', string='Customer')
picking_id = fields.Many2one('stock.picking', string='Picking')
sale_id = fields.Many2one('sale.order', string='Sale Order')
+
report_logbook_sj_id = fields.Many2one('report.logbook.sj', string='Logbook SJ')
not_exist = fields.Boolean(string='Not Exist')
note = fields.Char(string='Note')
+
+ sequence = fields.Integer(string='Sequence', default=0, index=True)
+
+ line_num = fields.Integer(string='No', compute='_compute_line_num', store=False)
+
+ @api.depends(
+ 'report_logbook_sj_id.report_logbook_sj_line',
+ 'report_logbook_sj_id.report_logbook_sj_line.sequence'
+ )
+ def _compute_line_num(self):
+ for parent in self.mapped('report_logbook_sj_id'):
+ lines = parent.report_logbook_sj_line.sorted(key=lambda l: (l.sequence or 0, l.id))
+ for i, l in enumerate(lines, start=1):
+ l.line_num = i
+ for rec in self.filtered(lambda r: not r.report_logbook_sj_id):
+ rec.line_num = 0
+
+ @api.model
+ def create(self, vals):
+ if not vals.get('sequence') and vals.get('report_logbook_sj_id'):
+ last = self.search(
+ [('report_logbook_sj_id', '=', vals['report_logbook_sj_id'])],
+ order='sequence desc, id desc', limit=1
+ )
+ vals['sequence'] = (last.sequence or 0) + 1
+ return super().create(vals)
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 76d4d7e7..136663ba 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -234,9 +234,9 @@ class SaleOrder(models.Model):
customer_type = fields.Selection([
('pkp', 'PKP'),
('nonpkp', 'Non PKP')
- ], required=True, compute='_compute_partner_field')
- sppkp = fields.Char(string="SPPKP", required=True, tracking=True, compute='_compute_partner_field')
- npwp = fields.Char(string="NPWP", required=True, tracking=True, compute='_compute_partner_field')
+ ], related="partner_id.customer_type", string="Customer Type", readonly=True)
+ sppkp = fields.Char(string="SPPKP", related="partner_id.sppkp")
+ npwp = fields.Char(string="NPWP", related="partner_id.npwp")
purchase_total = fields.Monetary(string='Purchase Total', compute='_compute_purchase_total')
voucher_id = fields.Many2one(comodel_name='voucher', string='Voucher', copy=False)
applied_voucher_id = fields.Many2one(comodel_name='voucher', string='Applied Voucher', copy=False)
@@ -1674,7 +1674,7 @@ class SaleOrder(models.Model):
rec.expected_ready_to_ship = eta_date
@api.depends("order_line.product_id", "date_order")
- def _compute_etrts_date(self): # Function to calculate Estimated Ready To Ship Date
+ def _compute_etrts_date(self):
self._calculate_etrts_date()
@@ -1844,9 +1844,9 @@ class SaleOrder(models.Model):
def override_allow_create_invoice(self):
if not self.env.user.is_accounting:
raise UserError('Hanya Finance Accounting yang dapat klik tombol ini')
- for term in self.payment_term_id.line_ids:
- if term.days > 0:
- raise UserError('Hanya dapat digunakan pada Cash Before Delivery')
+ # for term in self.payment_term_id.line_ids:
+ # if term.days > 0:
+ # raise UserError('Hanya dapat digunakan pada Cash Before Delivery')
for line in self.order_line:
line.qty_to_invoice = line.product_uom_qty
@@ -2049,22 +2049,22 @@ class SaleOrder(models.Model):
# return [('id', 'not in', order_ids)]
# return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)]
- @api.depends('partner_id')
- def _compute_partner_field(self):
- for order in self:
- partner = order.partner_id.parent_id or order.partner_id
- order.npwp = partner.npwp
- order.sppkp = partner.sppkp
- order.customer_type = partner.customer_type
+ # @api.depends('partner_id')
+ # def _compute_partner_field(self):
+ # for order in self:
+ # partner = order.partner_id.parent_id or order.partner_id
+ # order.npwp = partner.npwp
+ # order.sppkp = partner.sppkp
+ # order.customer_type = partner.customer_type
@api.onchange('partner_id')
def onchange_partner_contact(self):
parent_id = self.partner_id.parent_id
parent_id = parent_id if parent_id else self.partner_id
- self.npwp = parent_id.npwp
- self.sppkp = parent_id.sppkp
- self.customer_type = parent_id.customer_type
+ # self.npwp = parent_id.npwp
+ # self.sppkp = parent_id.sppkp
+ # self.customer_type = parent_id.customer_type
self.email = parent_id.email
self.pareto_status = parent_id.pareto_status
self.user_id = parent_id.user_id
@@ -2141,9 +2141,15 @@ class SaleOrder(models.Model):
if self.state not in ['draft', 'sent']:
raise UserError("Status harus draft atau sent")
- self._validate_npwp()
-
def _validate_npwp(self):
+ if not self.npwp:
+ raise UserError("NPWP partner kosong, silahkan isi terlebih dahulu npwp nya di contact partner")
+
+ if not self.customer_type:
+ raise UserError("Customer Type partner kosong, silahkan isi terlebih dahulu Customer Type nya di contact partner")
+
+ if not self.sppkp:
+ raise UserError("SPPKP partner kosong, silahkan isi terlebih dahulu SPPKP nya di contact partner")
num_digits = sum(c.isdigit() for c in self.npwp)
if num_digits < 10:
@@ -2157,6 +2163,7 @@ class SaleOrder(models.Model):
self._validate_order()
for order in self:
+ order._validate_npwp()
order._validate_uniform_taxes()
order.order_line.validate_line()
@@ -2211,9 +2218,8 @@ class SaleOrder(models.Model):
if self.validate_different_vendor() and not self.vendor_approval:
return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor')
self.check_due()
-
- self._validate_order()
for order in self:
+ order._validate_npwp()
order._validate_delivery_amt()
order._validate_uniform_taxes()
order.order_line.validate_line()
@@ -2480,6 +2486,7 @@ class SaleOrder(models.Model):
order.check_data_real_delivery_address()
order.sale_order_check_approve()
order._validate_order()
+ order._validate_npwp()
order.order_line.validate_line()
main_parent = order.partner_id.get_main_parent()
@@ -2637,7 +2644,7 @@ class SaleOrder(models.Model):
if user.is_leader or user.is_sales_manager:
return True
- if user.id in (3401, 20, 3988): # admin (fida, nabila, ninda)
+ if user.id in (3401, 20, 3988, 17340): # admin (fida, nabila, ninda)
return True
if self.env.context.get("ask_approval") and user.id in (3401, 20, 3988):
@@ -2665,23 +2672,17 @@ class SaleOrder(models.Model):
def _set_sppkp_npwp_contact(self):
partner = self.partner_id.parent_id or self.partner_id
- if not partner.sppkp:
- partner.sppkp = self.sppkp
- if not partner.npwp:
- partner.npwp = self.npwp
+ # if not partner.sppkp:
+ # partner.sppkp = self.sppkp
+ # if not partner.npwp:
+ # partner.npwp = self.npwp
if not partner.email:
partner.email = self.email
- if not partner.customer_type:
- partner.customer_type = self.customer_type
+ # if not partner.customer_type:
+ # partner.customer_type = self.customer_type
if not partner.user_id:
partner.user_id = self.user_id.id
- # if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type:
- # partner.customer_type = self.customer_type
- # partner.npwp = self.npwp
- # partner.sppkp = self.sppkp
- # partner.email = self.email
-
def _compute_total_margin(self):
for order in self:
total_margin = sum(line.item_margin for line in order.order_line if line.product_id)
@@ -3123,52 +3124,6 @@ class SaleOrder(models.Model):
# order._update_partner_details()
return order
- # def write(self, vals):
- # Call the super method to handle the write operation
- # res = super(SaleOrder, self).write(vals)
- # self._compute_etrts_date()
- # Check if the update is coming from a save operation
- # if any(field in vals for field in ['sppkp', 'npwp', 'email', 'customer_type']):
- # self._update_partner_details()
-
- # return res
-
- def _update_partner_details(self):
- for order in self:
- partner = order.partner_id.parent_id or order.partner_id
- if partner:
- # Update partner details
- partner.sppkp = order.sppkp
- partner.npwp = order.npwp
- partner.email = order.email
- partner.customer_type = order.customer_type
-
- # Save changes to the partner record
- partner.write({
- 'sppkp': partner.sppkp,
- 'npwp': partner.npwp,
- 'email': partner.email,
- 'customer_type': partner.customer_type,
- })
-
- # def write(self, vals):
- # for order in self:
- # if order.state in ['sale', 'cancel']:
- # if 'order_line' in vals:
- # new_lines = vals.get('order_line', [])
- # for command in new_lines:
- # if command[0] == 0: # A new line is being added
- # raise UserError(
- # "SO tidak dapat ditambahkan produk baru karena SO sudah menjadi sale order.")
- #
- # res = super(SaleOrder, self).write(vals)
- # # self._check_total_margin_excl_third_party()
- # if any(fields in vals for fields in ['delivery_amt', 'carrier_id', 'shipping_cost_covered']):
- # self._validate_delivery_amt()
- # if any(field in vals for field in ["order_line", "client_order_ref"]):
- # self._calculate_etrts_date()
- # return res
-
# @api.depends('commitment_date')
def _compute_ready_to_ship_status_detail(self):
def is_empty(val):
diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py
index 47a24264..1f2ea1fb 100644
--- a/indoteknik_custom/models/sale_order_line.py
+++ b/indoteknik_custom/models/sale_order_line.py
@@ -71,23 +71,17 @@ class SaleOrderLine(models.Model):
if order_qty > 0:
for move in line.move_ids:
- # --- CASE 1: Move belum selesai ---
if move.state not in ('done', 'cancel'):
reserved_qty += move.reserved_availability or 0.0
continue
- # --- CASE 2: Move sudah done ---
if move.location_dest_id.usage == 'customer':
- # Barang dikirim ke customer
delivered_qty += move.quantity_done or 0.0
elif move.location_id.usage == 'customer':
- # Barang balik dari customer (retur)
delivered_qty -= move.quantity_done or 0.0
- # Clamp supaya delivered gak minus
delivered_qty = max(delivered_qty, 0)
- # Hitung persen
line.reserved_percent = min((reserved_qty / order_qty) * 100, 100) if order_qty else 0
line.delivered_percent = min((delivered_qty / order_qty) * 100, 100) if order_qty else 0
line.unreserved_percent = max(100 - line.reserved_percent - line.delivered_percent, 0)
diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py
index 6e839bf0..c683f75a 100644
--- a/indoteknik_custom/models/tukar_guling.py
+++ b/indoteknik_custom/models/tukar_guling.py
@@ -61,7 +61,7 @@ class TukarGuling(models.Model):
notes = fields.Text('Notes')
return_type = fields.Selection(String='Return Type', selection=[
('tukar_guling', 'Tukar Guling'), # -> barang yang sama
- ('revisi_so', 'Revisi SO')], required=True, tracking=3)
+ ('retur_so', 'Retur SO')], required=True, tracking=3, help='Retur SO (ORT-SRT),\n Tukar Guling (ORT-SRT-PICK-OUT)')
state = fields.Selection(string='Status', selection=[
('draft', 'Draft'),
('approval_sales', ' Approval Sales'),
@@ -169,7 +169,7 @@ class TukarGuling(models.Model):
raise UserError("❌ Picking type harus BU/OUT atau BU/PICK")
for rec in self:
if rec.operations and rec.operations.picking_type_id.id == 30:
- rec.return_type = 'revisi_so'
+ rec.return_type = 'retur_so'
if self.operations:
from_return_picking = self.env.context.get('from_return_picking', False) or \
@@ -315,7 +315,7 @@ class TukarGuling(models.Model):
@api.constrains('return_type', 'operations')
def _check_required_bu_fields(self):
for record in self:
- if record.return_type in ['revisi_so', 'tukar_guling'] and not record.operations:
+ if record.return_type in ['retur_so', 'tukar_guling'] and not record.operations:
raise ValidationError("Operations harus diisi")
@api.constrains('line_ids', 'state')
@@ -352,16 +352,16 @@ class TukarGuling(models.Model):
# ('state', '!=', 'cancel')
# ]) > 0
- # def _check_invoice_on_revisi_so(self):
+ # def _check_invoice_on_retur_so(self):
# for record in self:
- # if record.return_type == 'revisi_so' and record.origin:
+ # if record.return_type == 'retur_so' and record.origin:
# invoices = self.env['account.move'].search([
# ('invoice_origin', 'ilike', record.origin),
# ('state', 'not in', ['draft', 'cancel'])
# ])
# if invoices:
# raise ValidationError(
- # _("Tidak bisa memilih Return Type 'Revisi SO' karena dokumen %s sudah dibuat invoice.") % record.origin
+ # _("Tidak bisa memilih Return Type 'Retur SO' karena dokumen %s sudah dibuat invoice.") % record.origin
# )
@@ -414,7 +414,7 @@ class TukarGuling(models.Model):
self.ensure_one()
if self.operations.picking_type_id.id not in [29, 30]:
raise UserError("❌ Picking type harus BU/OUT atau BU/PICK")
- # self._check_invoice_on_revisi_so()
+ # self._check_invoice_on_retur_so()
operasi = self.operations.picking_type_id.id
tipe = self.return_type
pp = vals.get('return_type', tipe)
@@ -530,7 +530,7 @@ class TukarGuling(models.Model):
raise UserError(
_("Qty di Koli tidak sesuai dengan qty retur untuk produk %s") % line.product_id.display_name
)
- # self._check_invoice_on_revisi_so()
+ # self._check_invoice_on_retur_so()
self._validate_product_lines()
if self.state != 'draft':
@@ -553,7 +553,7 @@ class TukarGuling(models.Model):
self.state = 'done'
# OUT revisi SO
- elif self.operations.picking_type_id.id == 29 and self.return_type == 'revisi_so':
+ elif self.operations.picking_type_id.id == 29 and self.return_type == 'retur_so':
total_ort = self.env['stock.picking'].search_count([
('tukar_guling_id', '=', self.id),
('picking_type_id', '=', 74),
@@ -567,7 +567,7 @@ class TukarGuling(models.Model):
self.state = 'done'
# PICK revisi SO
- elif self.operations.picking_type_id.id == 30 and self.return_type == 'revisi_so':
+ elif self.operations.picking_type_id.id == 30 and self.return_type == 'retur_so':
done_ort = self.env['stock.picking'].search([
('tukar_guling_id', '=', self.id),
('picking_type_id', '=', 74),
@@ -581,7 +581,7 @@ class TukarGuling(models.Model):
def action_approve(self):
self.ensure_one()
self._validate_product_lines()
- # self._check_invoice_on_revisi_so()
+ # self._check_invoice_on_retur_so()
self._check_not_allow_tukar_guling_on_bu_pick()
operasi = self.operations.picking_type_id.id
@@ -631,7 +631,7 @@ class TukarGuling(models.Model):
elif rec.state == 'approval_finance':
if not rec.env.user.has_group('indoteknik_custom.group_role_fat'):
raise UserError("Hanya Finance Manager yang boleh approve tahap ini.")
- # rec._check_invoice_on_revisi_so()
+ # rec._check_invoice_on_retur_so()
rec.set_opt()
rec.state = 'approval_logistic'
rec.date_finance = now
@@ -710,7 +710,7 @@ class TukarGuling(models.Model):
### ======== SRT dari BU/OUT =========
srt_return_lines = []
- if mapping_koli:
+ if mapping_koli and record.operations.picking_type_id.id == 29:
for prod in mapping_koli.mapped('product_id'):
qty_total = sum(mk.qty_return for mk in mapping_koli.filtered(lambda m: m.product_id == prod))
move = bu_out.move_lines.filtered(lambda m: m.product_id == prod)
@@ -723,7 +723,7 @@ class TukarGuling(models.Model):
}))
_logger.info(f"📟 SRT line: {prod.display_name} | qty={qty_total}")
- elif not mapping_koli:
+ elif not mapping_koli and record.operations.picking_type_id.id == 29:
for line in record.line_ids:
move = bu_out.move_lines.filtered(lambda m: m.product_id == line.product_id)
if not move:
diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py
index f2f37606..f61b3828 100644
--- a/indoteknik_custom/models/tukar_guling_po.py
+++ b/indoteknik_custom/models/tukar_guling_po.py
@@ -38,9 +38,9 @@ class TukarGulingPO(models.Model):
)
ba_num = fields.Char('Nomor BA', tracking=3)
return_type = fields.Selection([
- ('revisi_po', 'Revisi PO'),
+ ('retur_po', 'Retur PO'),
('tukar_guling', 'Tukar Guling'),
- ], string='Return Type', required=True, tracking=3)
+ ], string='Return Type', required=True, tracking=3, help='Retur PO (VRT-PRT),\n Tukar Guling (VRT-PRT-INPUT-PUT')
notes = fields.Text('Notes', tracking=3)
tukar_guling_po_id = fields.Many2one('tukar.guling.po', string='Tukar Guling PO', ondelete='cascade')
line_ids = fields.One2many('tukar.guling.line.po', 'tukar_guling_po_id', string='Product Lines', tracking=3)
@@ -143,9 +143,9 @@ class TukarGulingPO(models.Model):
return res
- # def _check_bill_on_revisi_po(self):
+ # def _check_bill_on_retur_po(self):
# for record in self:
- # if record.return_type == 'revisi_po' and record.origin:
+ # if record.return_type == 'retur_po' and record.origin:
# bills = self.env['account.move'].search([
# ('invoice_origin', 'ilike', record.origin),
# ('move_type', '=', 'in_invoice'), # hanya vendor bill
@@ -153,7 +153,7 @@ class TukarGulingPO(models.Model):
# ])
# if bills:
# raise ValidationError(
- # _("Tidak bisa memilih Return Type 'Revisi PO' karena PO %s sudah dibuat vendor bill. Harus Cancel Jika ingin melanjutkan") % record.origin
+ # _("Tidak bisa memilih Return Type 'Retur PO' karena PO %s sudah dibuat vendor bill. Harus Cancel Jika ingin melanjutkan") % record.origin
# )
@api.onchange('operations')
@@ -284,7 +284,7 @@ class TukarGulingPO(models.Model):
@api.constrains('return_type', 'operations')
def _check_required_bu_fields(self):
for record in self:
- if record.return_type in ['revisi_po', 'tukar_guling'] and not record.operations:
+ if record.return_type in ['retur_po', 'tukar_guling'] and not record.operations:
raise ValidationError("Operations harus diisi")
@api.constrains('line_ids', 'state')
@@ -350,7 +350,7 @@ class TukarGulingPO(models.Model):
def write(self, vals):
if self.operations.picking_type_id.id not in [75, 28]:
raise UserError("❌ Tidak bisa retur bukan BU/INPUT atau BU/PUT!")
- # self._check_bill_on_revisi_po()
+ # self._check_bill_on_retur_po()
tipe = vals.get('return_type', self.return_type)
if self.operations and self.operations.picking_type_id.id == 28 and tipe == 'tukar_guling':
@@ -418,7 +418,7 @@ class TukarGulingPO(models.Model):
def action_submit(self):
self.ensure_one()
- # self._check_bill_on_revisi_po()
+ # self._check_bill_on_retur_po()
self._validate_product_lines()
self._check_not_allow_tukar_guling_on_bu_input()
@@ -463,7 +463,7 @@ class TukarGulingPO(models.Model):
def action_approve(self):
self.ensure_one()
self._validate_product_lines()
- # self._check_bill_on_revisi_po()
+ # self._check_bill_on_retur_po()
self._check_not_allow_tukar_guling_on_bu_input()
if not self.operations:
@@ -485,7 +485,7 @@ class TukarGulingPO(models.Model):
elif rec.state == 'approval_finance':
if not rec.env.user.has_group('indoteknik_custom.group_role_fat'):
raise UserError("Hanya Finance yang boleh approve tahap ini.")
- # rec._check_bill_on_revisi_po()
+ # rec._check_bill_on_retur_po()
rec.set_opt()
rec.state = 'approval_logistic'
rec.date_finance = now
@@ -501,7 +501,7 @@ class TukarGulingPO(models.Model):
def update_doc_state(self):
# bu input rev po
- if self.operations.picking_type_id.id == 28 and self.return_type == 'revisi_po':
+ if self.operations.picking_type_id.id == 28 and self.return_type == 'retur_po':
prt = self.env['stock.picking'].search([
('tukar_guling_po_id', '=', self.id),
('state', '=', 'done'),
@@ -510,7 +510,7 @@ class TukarGulingPO(models.Model):
if self.state == 'approved' and prt:
self.state = 'done'
# bu put rev po
- elif self.operations.picking_type_id.id == 75 and self.return_type == 'revisi_po':
+ elif self.operations.picking_type_id.id == 75 and self.return_type == 'retur_po':
total_prt = self.env['stock.picking'].search_count([
('tukar_guling_po_id', '=', self.id),
('picking_type_id.id', '=', 76)
diff --git a/indoteknik_custom/report/purchase_report.xml b/indoteknik_custom/report/purchase_report.xml
index 9d7f4028..d0b73118 100644
--- a/indoteknik_custom/report/purchase_report.xml
+++ b/indoteknik_custom/report/purchase_report.xml
@@ -25,96 +25,113 @@
</t>
</template>
- <!-- Document Template -->
-<template id="report_purchaseorder_website_document">
- <t t-call="web.external_layout">
+ <template id="report_purchaseorder_website_document">
+ <t t-call="web.html_container">
<t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)" />
- <div class="page">
- <!-- Header Image -->
- <div class="mb16">
- <img src="https://erp.indoteknik.com/api/image/ir.attachment/datas/2498521"
- style="width:100%; max-height:100px; object-fit:contain;"/>
- </div>
+ <!-- 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 class="text-center mb4" style="color:#d32f2f; font-weight:bold;">
+ <!-- TITLE -->
+ <h2 style="text-align:center; margin:8px 0 0 0; color:#d32f2f; font-weight:800; letter-spacing:1px;">
PURCHASE ORDER
</h2>
- <h4 class="text-center mb32">
+ <h4 style="text-align:center; margin:4px 0 20px 0; font-weight:normal; color:#555;">
No. <span t-field="doc.name"/>
</h4>
- <!-- Top Info sejajar -->
- <div class="row mb16" style="font-size:12px;">
- <div class="col-4">
- <strong>Term Of Payment:</strong>
- <span t-field="doc.payment_term_id.name"/>
- </div>
- <div class="col-4">
- <strong>Order Date:</strong>
- <span t-field="doc.date_order" t-options='{"widget": "date"}'/>
- </div>
- <div class="col-4">
- <strong>Responsible:</strong>
- <span t-field="doc.user_id"/>
- </div>
- </div>
+ <!-- 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 & Shipping Info sejajar -->
- <div class="row mb32" style="font-size:12px;">
- <div class="col-6" style="border:1px solid #ccc; padding:8px;">
- <strong>Alamat Pengiriman:</strong><br/>
- PT Indoteknik (Bandengan 1 Depan)<br/>
- Jl. Bandengan Utara Komp A 8 B<br/>
- RT. Penjaringan, Kec. Penjaringan, Jakarta (BELAKANG INDOMARET)<br/>
- JK 14440<br/>
- Indonesia
- </div>
- <div class="col-6" style="border:1px solid #ccc; padding:8px;">
- <strong>Nama Vendor:</strong><br/>
- <div t-field="doc.partner_id"
- t-options='{"widget": "contact", "fields": ["address", "name", "phone"],
- "no_marker": True, "phone_icons": True}'/>
- </div>
- </div>
+ <!-- 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 (Bandengan 1 Depan)<br/>
+ Jl. Bandengan Utara No. 89, RT 003<br/>
+ RT. Penjaringan, Kec. Penjaringan, Jakarta (BELAKANG INDOMARET)<br/>
+ JK 14440 - Indonesia
+ </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 class="table table-sm o_main_table" style="font-size:11px; border:1px solid #000; border-collapse: collapse; width:100%;">
- <thead style="display: table-row-group; background:#f5f5f5;">
- <tr>
- <th style="border:1px solid #000; padding:4px;">Description</th>
- <th class="text-right" style="border:1px solid #000; padding:4px;">Quantity</th>
- <th class="text-right" style="border:1px solid #000; padding:4px;">Unit Price</th>
- <th class="text-right" style="border:1px solid #000; padding:4px;">Taxes</th>
- <th class="text-right" style="border:1px solid #000; padding:4px;">Subtotal</th>
- </tr>
- </thead>
+ <!-- ORDER LINES -->
+ <table style="border-collapse:collapse; width:100%; margin-top:16px; font-size:14px;">
<tbody>
- <t t-foreach="doc.order_line" t-as="line">
- <!-- Main row -->
- <tr>
- <td style="border:1px solid #000; padding:4px;">
- <span t-field="line.name"/>
+ <!-- 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-esc="line.name"/>
+ </span>
+ </div>
</td>
- <td class="text-right" style="border:1px solid #000; padding:4px;">
- <span t-field="line.product_qty"/>
- <span t-field="line.product_uom"/>
+
+ <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>
- <td class="text-right" style="border:1px solid #000; padding:4px;">
+
+ <!-- UNIT PRICE -->
+ <td style="border:1px solid #ccc; padding:6px; text-align:center;">
<span t-field="line.price_unit"/>
</td>
- <td class="text-right" style="border:1px solid #000; padding:4px;">
+
+ <!-- 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>
- <td class="text-right" style="border:1px solid #000; padding:4px;">
+
+ <!-- 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 row -->
- <t t-if="line.product_id.website_description">
- <tr>
- <td colspan="5" style="border:1px solid #000; padding:6px; font-size:10px; color:#555;">
+
+ <!-- WEBSITE DESCRIPTION -->
+ <t t-if="line.show_description">
+ <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>
@@ -123,40 +140,38 @@
</tbody>
</table>
- <!-- Totals -->
- <div class="clearfix">
- <div class="row">
- <div class="col-4 ml-auto">
- <table class="table table-sm" style="border:1px solid #000; border-collapse: collapse; width:100%;">
- <tr>
- <td style="border:1px solid #000; padding:4px;"><strong>Subtotal</strong></td>
- <td class="text-right" style="border:1px solid #000; padding:4px;">
- <span t-field="doc.amount_untaxed"/>
- </td>
- </tr>
- <tr>
- <td style="border:1px solid #000; padding:4px;">Taxes</td>
- <td class="text-right" style="border:1px solid #000; padding:4px;">
- <span t-field="doc.amount_tax"/>
- </td>
- </tr>
- <tr class="o_total">
- <td style="border:1px solid #000; padding:4px;"><strong>Total</strong></td>
- <td class="text-right" style="border:1px solid #000; padding:4px;">
- <span t-field="doc.amount_total"/>
- </td>
- </tr>
- </table>
- </div>
- </div>
- </div>
- <!-- Notes -->
- <div class="mt32" style="font-size:11px;">
+ <!-- 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>
+ </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/views/approval_payment_term.xml b/indoteknik_custom/views/approval_payment_term.xml
index 5c130f3f..b0b99689 100644
--- a/indoteknik_custom/views/approval_payment_term.xml
+++ b/indoteknik_custom/views/approval_payment_term.xml
@@ -7,7 +7,7 @@
<tree default_order="create_date desc">
<field name="number"/>
<field name="partner_id"/>
- <field name="parent_id"/>
+ <field name="parent_id" optional="hide"/>
<field name="property_payment_term_id"/>
<field name="create_date" optional="hide"/>
<field name="approve_date" optional="hide"/>
diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml
index f624c42e..51377f78 100644
--- a/indoteknik_custom/views/dunning_run.xml
+++ b/indoteknik_custom/views/dunning_run.xml
@@ -25,13 +25,14 @@
<field name="arch" type="xml">
<tree>
<field name="partner_id"/>
+ <field name="reference"/>
<field name="invoice_id"/>
<field name="date_invoice"/>
- <field name="efaktur_id"/>
- <field name="reference"/>
+ <field name="efaktur_id" optional="hide"/>
<field name="total_amt" sum="Grand Total Amount"/>
<field name="open_amt"/>
<field name="due_date"/>
+ <field name="payment_term"/>
</tree>
</field>
</record>
diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml
index 821f3295..a0ac9824 100755
--- a/indoteknik_custom/views/purchase_order.xml
+++ b/indoteknik_custom/views/purchase_order.xml
@@ -99,6 +99,7 @@
<field name="total_delivery_amt" attrs="{'required': [('partner_id', 'in', [9688, 29712])]}"/>
<field name="product_bom_id" attrs="{'invisible': [('product_bom_id', '=', None)]}"/>
<field name="manufacturing_id" attrs="{'invisible': [('product_bom_id', '=', None)]}"/>
+ <field name="show_description" attrs="{'invisible': [('partner_id', '!=', 5571)]}" widget="boolean_toggle"/>
<!-- <field name="move_id" domain="[('move_type','=','entry')]" context="{'form_view_ref': 'account.view_move_form'}" options="{'no_create': True}"/> -->
</field>
<field name="amount_total" position="after">
@@ -112,6 +113,7 @@
</field>
<field name="product_id" position="before">
<field name="line_no" attrs="{'readonly': 1}" optional="hide"/>
+ <field name="show_description" optional="hide" widget="boolean_toggle"/>
</field>
<field name="product_id" position="attributes">
<attribute name="options">{'no_create': True}</attribute>
@@ -181,19 +183,20 @@
</field>
<field name="order_line" position="attributes">
- <attribute name="attrs">{'readonly': ['|', ('state', 'in', ['purchase', 'done', 'cancel']), ('has_active_invoice', '=', True)]}</attribute>
+ <!-- <attribute name="attrs">{'readonly': ['|', ('state', 'in', ['purchase', 'done', 'cancel']), ('has_active_invoice', '=', True)]}</attribute> -->
+ <attribute name="attrs">{'readonly': [('has_active_invoice', '=', True)]}</attribute>
</field>
<xpath expr="//form/sheet/notebook/page/field[@name='order_line']/tree/field[@name='price_unit']" position="attributes">
- <attribute name="attrs">{'readonly': [], 'required': True}</attribute>
+ <attribute name="attrs">{'readonly': [('state', 'in', ['purchase', 'done', 'cancel'])], 'required': True}</attribute>
</xpath>
<xpath expr="//form/sheet/notebook/page/field[@name='order_line']/tree/field[@name='taxes_id']" position="attributes">
- <attribute name="attrs">{'readonly': []}</attribute>
+ <attribute name="attrs">{'readonly': [('state', 'in', ['purchase', 'done', 'cancel'])]}</attribute>
</xpath>
<xpath expr="//form/sheet/notebook/page/field[@name='order_line']/tree/field[@name='product_qty']" position="attributes">
- <attribute name="attrs">{'required': True}</attribute>
+ <attribute name="attrs">{'readonly': [('state', 'in', ['purchase', 'done', 'cancel'])], 'required': True}</attribute>
</xpath>
<xpath expr="//form/sheet/notebook/page[@name='purchase_delivery_invoice']" position="before">
diff --git a/indoteknik_custom/views/report_logbook_sj.xml b/indoteknik_custom/views/report_logbook_sj.xml
index 94f6c2ab..2b7cfa22 100644
--- a/indoteknik_custom/views/report_logbook_sj.xml
+++ b/indoteknik_custom/views/report_logbook_sj.xml
@@ -21,6 +21,8 @@
<field name="model">report.logbook.sj.line</field>
<field name="arch" type="xml">
<tree editable="bottom">
+<!-- <field name="sequence" widget="handle"/>-->
+ <field name="line_num" string="No" readonly="1"/>
<field name="name"/>
<field name="driver_id"/>
<field name="departure_date"/>
diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml
index 7d5be3b7..c32151d8 100644
--- a/indoteknik_custom/views/res_partner.xml
+++ b/indoteknik_custom/views/res_partner.xml
@@ -36,9 +36,9 @@
<field name="pareto_status"/>
<field name="digital_invoice_tax"/>
</field>
- <field name="nama_wajib_pajak" position="attributes">
+ <!-- <field name="nama_wajib_pajak" position="attributes">
<attribute name="required">1</attribute>
- </field>
+ </field> -->
<field name="kota_id" position="attributes">
<attribute name="required">0</attribute>
</field>
@@ -48,14 +48,14 @@
<field name="kelurahan_id" position="attributes">
<attribute name="required">0</attribute>
</field>
- <field name="npwp" position="attributes">
+ <!-- <field name="npwp" position="attributes">
<attribute name="required">1</attribute>
</field>
<field name="alamat_lengkap_text" position="attributes">
<attribute name="required">1</attribute>
- </field>
+ </field> -->
<field name="npwp" position="before">
- <field name="customer_type" required="1"/>
+ <field name="customer_type"/>
</field>
<field name="alamat_lengkap_text" position="after">
<field name="nitku" />
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index 326fd560..8d56bbbd 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -148,9 +148,9 @@
<field name="pareto_status"/>
</field>
<field name="analytic_account_id" position="after">
- <field name="customer_type" readonly="1"/>
- <field name="npwp" placeholder='99.999.999.9-999.999' readonly="1"/>
- <field name="sppkp" attrs="{'required': [('customer_type', '=', 'pkp')]}" readonly="1"/>
+ <field name="customer_type"/>
+ <field name="npwp" placeholder='99.999.999.9-999.999'/>
+ <field name="sppkp" attrs="{'required': [('customer_type', '=', 'pkp')]}"/>
<field name="email" required="1"/>
<field name="unreserve_id"/>
<field name="due_id" readonly="1"/>
@@ -297,9 +297,9 @@
<field name="note" optional="hide"/>
<field name="note_procurement" optional="hide"/>
<field name="vendor_subtotal" optional="hide"/>
- <field name="unreserved_percent" widget="percentpie" string="Unreserved"/>
- <field name="reserved_percent" widget="percentpie" string="Reserved"/>
- <field name="delivered_percent" widget="percentpie" string="Delivered"/>
+ <field name="unreserved_percent" widget="percentpie" string="Unreserved" optional="hide"/>
+ <field name="reserved_percent" widget="percentpie" string="Reserved" optional="hide"/>
+ <field name="delivered_percent" widget="percentpie" string="Delivered" optional="hide"/>
<field name="weight" optional="hide"/>
<field name="is_has_disc" string="Flash Sale Item?" readonly="1" optional="hide"/>
<field name="amount_voucher_disc" string="Voucher" readonly="1" optional="hide"/>
diff --git a/indoteknik_custom/views/tukar_guling_po.xml b/indoteknik_custom/views/tukar_guling_po.xml
index 548a209f..4a9ab25d 100644
--- a/indoteknik_custom/views/tukar_guling_po.xml
+++ b/indoteknik_custom/views/tukar_guling_po.xml
@@ -87,7 +87,7 @@
<!-- <field name="srt_num" readonly="1"/>-->
<field name="operations" string="Operations"
attrs="{
- 'required': [('return_type', 'in', ['revisi_po', 'tukar_guling'])]
+ 'required': [('return_type', 'in', ['retur_po', 'tukar_guling'])]
}"/>
<!-- <field name="origin" readonly="1"/>-->
<field name="origin_po" readonly="1"/>