summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2025-08-20 09:06:33 +0700
committerit-fixcomart <it@fixcomart.co.id>2025-08-20 09:06:33 +0700
commitbbc454fd6e13d12e9674769a555264f2c2343b5b (patch)
treed4973e8aab48e52cc0006600306ff7b19c11d639
parent9ea33822721c3c548675633effdf679cc1a99b0d (diff)
<hafid> refund system sisa uang muka
-rw-r--r--indoteknik_custom/models/refund_sale_order.py226
-rwxr-xr-xindoteknik_custom/models/sale_order.py80
-rw-r--r--indoteknik_custom/views/refund_sale_order.xml40
-rwxr-xr-xindoteknik_custom/views/sale_order.xml4
4 files changed, 292 insertions, 58 deletions
diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py
index 077809e9..2dc72f0f 100644
--- a/indoteknik_custom/models/refund_sale_order.py
+++ b/indoteknik_custom/models/refund_sale_order.py
@@ -17,13 +17,17 @@ class RefundSaleOrder(models.Model):
note_refund = fields.Text(string='Note Refund')
sale_order_ids = fields.Many2many('sale.order', string='Sales Order Numbers')
uang_masuk = fields.Float(string='Uang Masuk', required=True)
- total_invoice = fields.Float(string='Total Invoice')
+ total_invoice = fields.Float(string='Total Order')
ongkir = fields.Float(string='Ongkir', required=True, default=0.0)
amount_refund = fields.Float(string='Total Refund', required=True)
amount_refund_text = fields.Char(string='Total Refund Text', compute='_compute_refund_text')
user_ids = fields.Many2many('res.users', string='Salespersons', compute='_compute_user_ids', domain=[('active', 'in', [True, False])])
create_uid = fields.Many2one('res.users', string='Created By', readonly=True)
created_date = fields.Date(string='Tanggal Request Refund', readonly=True)
+ sale_order_count = fields.Integer(
+ string="Sale Order Count",
+ compute="_compute_sale_order_count",
+ )
status = fields.Selection([
('draft', 'Draft'),
('pengajuan1', 'Approval Sales Manager'),
@@ -55,7 +59,7 @@ class RefundSaleOrder(models.Model):
('uang', 'Refund Lebih Bayar'),
('retur_half', 'Refund Retur Sebagian'),
('retur', 'Refund Retur Full'),
- ('lainnya', 'Lainnya')
+ ('salah_transfer', 'Salah Transfer')
], string='Refund Type', required=True)
refund_type_display = fields.Char(string="Refund Type Label", compute="_compute_refund_type_display")
@@ -89,7 +93,7 @@ class RefundSaleOrder(models.Model):
bukti_refund_type = fields.Selection([
('pdf', 'PDF'),
('image', 'Image'),
- ], string="Attachment Type", default='image')
+ ], string="Attachment Type")
bukti_uang_masuk_image = fields.Binary(string="Upload Bukti Uang Masuk")
bukti_transfer_refund_image = fields.Binary(string="Upload Bukti Transfer Refund")
bukti_uang_masuk_pdf = fields.Binary(string="Upload Bukti Uang Masuk")
@@ -107,22 +111,44 @@ class RefundSaleOrder(models.Model):
is_locked = fields.Boolean(string="Locked", compute="_compute_is_locked")
sale_order_names_jasper = fields.Char(string='Sales Order List', compute='_compute_order_invoice_names')
invoice_names_jasper = fields.Char(string='Invoice List', compute='_compute_order_invoice_names')
-
-
-
- @api.depends('refund_type')
- def _compute_refund_type_display(self):
- for rec in self:
- rec.refund_type_display = dict(self.fields_get(allfields=['refund_type'])['refund_type']['selection']).get(rec.refund_type, '')
+ so_order_line_ids = fields.Many2many(
+ "sale.order.line", string="SO Order Lines", compute="_compute_so_order_lines", store=False
+ )
+ currency_id = fields.Many2one(
+ "res.currency", string="Currency",
+ default=lambda self: self.env.company.currency_id, required=True
+ )
+
+ amount_untaxed = fields.Monetary(
+ string="Untaxed Amount", compute="_compute_amount_from_so",
+ )
+ amount_tax = fields.Monetary(
+ string="Taxes", compute="_compute_amount_from_so",
+ )
+ amount_total = fields.Monetary(
+ string="Total", compute="_compute_amount_from_so",
+ )
+ total_margin = fields.Monetary(
+ string="Total Margin", compute="_compute_amount_from_so",
+ )
+ grand_total = fields.Monetary(
+ string="Grand Total", compute="_compute_amount_from_so",
+ )
+ delivery_amt = fields.Monetary(
+ string="Delivery Amount", help="Ongkos kirim yang Dibayarkan Customer", default=0.0, compute="_compute_amount_from_so",
+ )
+ remaining_refundable = fields.Float(
+ string="Sisa Uang Masuk",
+ help="Sisa uang masuk yang masih bisa direfund (hanya berlaku untuk 1 SO)",
+ )
-
@api.model
def create(self, vals):
allowed_user_ids = [23, 19, 688, 7]
if not (
self.env.user.has_group('indoteknik_custom.group_role_sales') or
self.env.user.has_group('indoteknik_custom.group_role_fat') or
- self.env.user.id not in allowed_user_ids
+ self.env.user.id in allowed_user_ids
):
raise UserError("❌ Hanya Sales dan Finance yang boleh membuat refund.")
@@ -158,9 +184,20 @@ class RefundSaleOrder(models.Model):
if refund_type in ['barang_kosong', 'barang_kosong_sebagian'] and so_ids:
sale_orders = self.env['sale.order'].browse(so_ids)
- zero_delivery_lines = sale_orders.mapped('order_line').filtered(lambda l: l.qty_delivered == 0)
- if not zero_delivery_lines:
- raise UserError("❌ Tidak ada barang yang Tidak Terikirim di Sales Order yang dipilih.")
+
+ if refund_type == 'barang_kosong':
+ zero_delivery_lines = sale_orders.mapped('order_line').filtered(
+ lambda l: l.qty_delivered == 0 and l.product_uom_qty > 0
+ )
+ if not zero_delivery_lines:
+ raise UserError("❌ Tidak ada barang kosong di SO yang terpilih.")
+
+ elif refund_type == 'barang_kosong_sebagian':
+ partial_delivery_lines = sale_orders.mapped('order_line').filtered(
+ lambda l: l.qty_delivered > 0 and l.product_uom_qty > l.qty_delivered
+ )
+ if not partial_delivery_lines:
+ raise UserError("❌ Tidak ada barang yang tidak Terkirim/Kosong di SO yang dipilih.")
if not so_ids and refund_type != 'lainnya':
@@ -180,22 +217,40 @@ class RefundSaleOrder(models.Model):
if refund_type == 'retur_half' and not invoice_ids:
raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk Retur Sebagian.")
- total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) if invoice_ids else 0.0
- ongkir = vals.get('ongkir', 0.0)
- vals['total_invoice'] = total_invoice
- pengurangan = total_invoice + ongkir
-
if refund_type == 'barang_kosong_sebagian' and so_ids:
sale_orders = self.env['sale.order'].browse(so_ids)
vals['uang_masuk'] = sum(sale_orders.mapped('amount_total'))
-
- uang_masuk = vals.get('uang_masuk', 0.0)
+ moves = self.env['account.move'].search([
+ ('sale_id', 'in', so_ids),
+ ('journal_id', '=', 11),
+ ('state', '=', 'posted'),
+ ])
+ total_uang_muka = sum(moves.mapped('amount_total_signed'))
- if uang_masuk > pengurangan:
- vals['amount_refund'] = uang_masuk - pengurangan
- else:
- raise UserError("Uang masuk harus lebih besar dari total invoice + ongkir untuk melakukan refund")
+ uang_masuk = total_uang_muka if moves else sum(self.env['sale.order'].browse(so_ids).mapped('gross_amount'))
+ vals['uang_masuk'] = uang_masuk
+ ongkir = vals.get('ongkir', 0.0)
+ total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) if invoice_ids else 0.0
+
+ vals['total_invoice'] = total_invoice
+ amount_refund = vals.get('amount_refund', 0.0)
+ if amount_refund <= 0.00:
+ raise ValidationError('Total Refund harus lebih dari 0 jika ingin mengajukan refund')
+
+ if so_ids and len(so_ids) > 1:
+ existing_refund = self.search([('sale_order_ids', 'in', so_ids)], limit=1)
+ if existing_refund:
+ raise UserError("❌ Refund multi SO hanya bisa 1 kali.")
+ vals['remaining_refundable'] = 0.0
+ elif so_ids and len(so_ids) == 1:
+ so = self.env['sale.order'].browse(so_ids[0])
+ existing_refunds = self.search([('sale_order_ids', 'in', so_ids)])
+ total_refunded = sum(existing_refunds.mapped('amount_refund')) + amount_refund
+ remaining = uang_masuk - total_refunded
+ if remaining < 0:
+ raise ValidationError("❌ Tidak ada sisa transaksi untuk di-refund di SO ini. Semua dana sudah dikembalikan.")
+ vals['remaining_refundable'] = remaining
return super().create(vals)
@@ -285,20 +340,41 @@ class RefundSaleOrder(models.Model):
if refund_type == 'retur_half' and not invoice_ids:
raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk retur sebagian.")
- if any(field in vals for field in ['uang_masuk', 'invoice_ids', 'ongkir', 'sale_order_ids']):
+ if any(field in vals for field in ['uang_masuk', 'invoice_ids', 'ongkir', 'sale_order_ids', 'amount_refund']):
total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed'))
vals['total_invoice'] = total_invoice
- uang_masuk = vals.get('uang_masuk', rec.uang_masuk)
- ongkir = vals.get('ongkir', rec.ongkir)
+ uang_masuk = rec.uang_masuk
+ amount_refund = vals.get('amount_refund', rec.amount_refund)
+
+ if amount_refund <= 0:
+ raise ValidationError("Total Refund harus lebih dari 0.")
+
+ existing_refunds = self.search([
+ ('sale_order_ids', 'in', so_ids),
+ ('id', '!=', rec.id)
+ ])
+ total_refunded = sum(existing_refunds.mapped('amount_refund')) + amount_refund
+ remaining = uang_masuk - total_refunded
- if uang_masuk <= (total_invoice + ongkir):
- raise UserError("Uang masuk harus lebih besar dari total invoice + ongkir")
- vals['amount_refund'] = uang_masuk - (total_invoice + ongkir)
+ if remaining < 0:
+ raise ValidationError("❌ Dana uang masuk telah sepenuhnya di refund tidak bisa Mengubah Nominal Refund")
- if vals.get('status') == 'refund' and not vals.get('refund_date'):
- vals['refund_date'] = fields.Date.context_today(self)
+ vals['remaining_refundable'] = remaining
return super().write(vals)
+
+ @api.onchange('ongkir', 'amount_refund')
+ def _onchange_refund_fields(self):
+ for rec in self:
+ uang_masuk = rec.uang_masuk or 0.0
+ ongkir = rec.ongkir or 0.0
+ refund_input = rec.amount_refund or 0.0
+
+ total_refund_with_ongkir = refund_input + ongkir
+ if total_refund_with_ongkir > uang_masuk:
+ raise UserError("❌ Refund + Ongkir tidak boleh melebihi Uang Masuk.")
+ remaining = uang_masuk - refund_input
+ rec.remaining_refundable = remaining
@api.depends('status_payment', 'status')
def _compute_is_locked(self):
@@ -362,6 +438,37 @@ class RefundSaleOrder(models.Model):
if self.sale_order_ids:
self.partner_id = self.sale_order_ids[0].partner_id
+ @api.constrains('sale_order_ids')
+ def _check_sale_orders_payment(self):
+ """ Validasi SO harus punya uang masuk (Journal Uang Muka / Midtrans) """
+ for rec in self:
+ invalid_orders = []
+ total_uang_masuk = 0.0
+
+ for so in rec.sale_order_ids:
+ # cari journal uang muka
+ moves = self.env['account.move'].search([
+ ('sale_id', '=', so.id),
+ ('journal_id', '=', 11), # Journal Uang Muka
+ ('state', '=', 'posted'),
+ ])
+
+ if not moves and so.payment_status != 'settlement':
+ invalid_orders.append(so.name)
+
+ if moves:
+ total_uang_muka = sum(moves.mapped('amount_total_signed')) or 0.0
+ total_uang_masuk += total_uang_muka
+ else:
+ # fallback Midtrans gross_amount
+ total_uang_masuk += so.gross_amount or 0.0
+
+ if invalid_orders:
+ raise ValidationError(
+ f"Tidak dapat membuat refund untuk SO {', '.join(invalid_orders)} "
+ "karena tidak memiliki Record Uang Masuk (Journal Uang Muka/Midtrans).\n"
+ "Pastikan semua SO yang dipilih sudah memiliki Record pembayaran yang valid."
+ )
@api.onchange('refund_type')
def _onchange_refund_type(self):
@@ -374,14 +481,12 @@ class RefundSaleOrder(models.Model):
line_vals.append((0, 0, {
'product_id': line.product_id.id,
'quantity': line.product_uom_qty,
+ 'product_from': line.order_id.name,
'reason': '',
}))
self.line_ids = line_vals
- if self.refund_type == 'barang_kosong_sebagian' and self.sale_order_ids:
- self.uang_masuk = sum(self.sale_order_ids.mapped('amount_total')) + sum(self.sale_order_ids.mapped('delivery_amt'))
-
elif self.refund_type in ['retur', 'retur_half'] and self.sale_order_ids:
line_vals = []
StockPicking = self.env['stock.picking']
@@ -476,6 +581,7 @@ class RefundSaleOrder(models.Model):
line_vals.append((0, 0, {
'product_id': line.product_id.id,
'quantity': line.product_uom_qty,
+ 'product_from': line.order_id.name,
'reason': '',
}))
res['line_ids'] = line_vals
@@ -671,7 +777,52 @@ class RefundSaleOrder(models.Model):
}
+ @api.depends(
+ "sale_order_ids",
+ "sale_order_ids.order_line.price_subtotal",
+ "sale_order_ids.order_line.price_tax",
+ "sale_order_ids.order_line.price_total",
+ "sale_order_ids.order_line.purchase_price",
+ "sale_order_ids.order_line.product_uom_qty",
+ "sale_order_ids.delivery_amt",
+ "sale_order_ids.shipping_cost_covered",
+ )
+ def _compute_amount_from_so(self):
+ for rec in self:
+ untaxed = tax = total_margin = delivery = 0.0
+ for so in rec.sale_order_ids:
+ if so.shipping_cost_covered == 'customer':
+ delivery += so.delivery_amt or 0.0
+ for line in so.order_line:
+ untaxed += line.price_subtotal
+ tax += line.price_tax
+ cost = line.purchase_price * line.product_uom_qty
+ margin = line.price_subtotal - cost
+ total_margin += margin
+ rec.amount_untaxed = untaxed
+ rec.amount_tax = tax
+ rec.amount_total = untaxed + tax
+ rec.total_margin = total_margin
+ rec.delivery_amt = delivery
+ rec.grand_total = rec.amount_total + rec.delivery_amt
+
+
+ @api.depends("sale_order_ids", "sale_order_ids.order_line")
+ def _compute_so_order_lines(self):
+ for rec in self:
+ rec.so_order_line_ids = rec.sale_order_ids.mapped("order_line")
+
+
+
+ @api.depends('refund_type')
+ def _compute_refund_type_display(self):
+ for rec in self:
+ rec.refund_type_display = dict(self.fields_get(allfields=['refund_type'])['refund_type']['selection']).get(rec.refund_type, '')
+
+ def _compute_sale_order_count(self):
+ for rec in self:
+ rec.sale_order_count = len(rec.sale_order_ids)
class RefundSaleOrderLine(models.Model):
_name = 'refund.sale.order.line'
@@ -682,3 +833,4 @@ class RefundSaleOrderLine(models.Model):
product_id = fields.Many2one('product.product', string='Product')
quantity = fields.Float(string='Qty')
reason = fields.Char(string='Reason')
+ product_from = fields.Char(string='Product Reference')
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index aa534d0c..2acee890 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -358,7 +358,6 @@ class SaleOrder(models.Model):
help="Tanggal pertama kali barang berhasil di-reservasi pada DO (BU/PICK/) yang berstatus Siap Dikirim."
)
refund_ids = fields.Many2many('refund.sale.order', compute='_compute_refund_ids', string='Refunds')
- has_refund = fields.Boolean(string='Has Refund', compute='_compute_has_refund')
refund_count = fields.Integer(string='Refund Count', compute='_compute_refund_count')
advance_payment_move_id = fields.Many2one(
'account.move',
@@ -3197,9 +3196,35 @@ class SaleOrder(models.Model):
def button_refund(self):
self.ensure_one()
+ moves = self.env['account.move'].search([
+ ('sale_id', '=', self.id),
+ ('journal_id', '=', 11),
+ ('state', '=', 'posted'),
+ ])
+
+ # Default 0
+ total_uang_muka = 0.0
+ has_moves = bool(moves)
+ has_settlement = self.payment_status == 'settlement'
+
+ if has_moves and has_settlement:
+ total_uang_muka = sum(moves.mapped('amount_total_signed')) + self.gross_amount
+ elif has_moves:
+ total_uang_muka = sum(moves.mapped('amount_total_signed'))
+ elif has_settlement:
+ total_uang_muka = self.gross_amount
+ else:
+ raise UserError(
+ "Tidak bisa melakukan refund karena SO tidak memiliki Record Uang Masuk "
+ "(Journal Uang Muka/Midtrans Payment)."
+ )
invoice_ids = self.invoice_ids.filtered(lambda inv: inv.state != 'cancel')
- total_so = sum(self.mapped('amount_total'))
+ total_refunded = sum(self.refund_ids.mapped('amount_refund')) or 0.0
+ sisa_uang_muka = total_uang_muka - total_refunded
+
+ if sisa_uang_muka <= 0:
+ raise UserError("❌ Tidak ada sisa transaksi untuk di-refund. Semua dana sudah dikembalikan.")
return {
'name': 'Refund Sale Order',
@@ -3210,9 +3235,9 @@ class SaleOrder(models.Model):
'context': {
'default_sale_order_ids': [(6, 0, [self.id])],
'default_invoice_ids': [(6, 0, invoice_ids.ids)],
- 'default_uang_masuk': total_so,
+ 'default_uang_masuk': sisa_uang_muka,
'default_ongkir': self.delivery_amt or 0.0,
- 'default_bank': '', # bisa isi default bank kalau mau
+ 'default_bank': '',
'default_account_name': '',
'default_account_no': '',
'default_refund_type': '',
@@ -3231,15 +3256,43 @@ class SaleOrder(models.Model):
if len(invoice_status_set) > 1:
raise UserError("Tidak dapat membuat refund untuk SO dengan status invoice berbeda. Harus memiliki status invoice yang sama.")
- already_refunded = self.filtered(lambda so: so.has_refund)
- if already_refunded:
- so_names = ', '.join(already_refunded.mapped('name'))
- raise UserError(f"❌ Tidak bisa refund ulang. {so_names} sudah melakukan refund.")
+ refunded_orders = self.filtered(lambda so: self.env['refund.sale.order'].search([('sale_order_ids', 'in', so.id)], limit=1))
+ if refunded_orders:
+ raise ValidationError(
+ f"SO {', '.join(refunded_orders.mapped('name'))} sudah pernah di-refund dan tidak bisa ikut dalam refund Multi SO."
+ )
+
+ total_uang_masuk = 0.0
+ invalid_orders=[]
+ for order in self:
+ moves = self.env['account.move'].search([
+ ('sale_id', '=', order.id),
+ ('journal_id', '=', 11),
+ ('state', '=', 'posted'),
+ ])
+
+ total_uang_muka = 0.0
+
+ if moves and order.payment_status == 'settlement':
+ total_uang_muka = order.gross_amount + sum(moves.mapped('amount_total_signed')) or 0.0
+ elif moves:
+ total_uang_muka = sum(moves.mapped('amount_total_signed')) or 0.0
+ elif order.payment_status == 'settlement':
+ total_uang_muka = order.gross_amount
+ else:
+ invalid_orders.append(order.name)
+
+ total_uang_masuk += total_uang_muka
+
+ if invalid_orders:
+ raise ValidationError(
+ f"Tidak dapat membuat refund untuk SO {', '.join(invalid_orders)} karena tidak memiliki Record Uang Masuk (Journal Uang Muka/Midtrans).\n"
+ "Pastikan semua SO yang dipilih sudah memiliki Record pembayaran yang valid."
+ )
+
invoice_ids = self.mapped('invoice_ids').filtered(lambda inv: inv.state != 'cancel')
delivery_total = sum(self.mapped('delivery_amt'))
- total_invoice = sum(invoice_ids.mapped('amount_total_signed'))
- total_so = sum(self.mapped('amount_total'))
return {
'type': 'ir.actions.act_window',
@@ -3250,7 +3303,7 @@ class SaleOrder(models.Model):
'context': {
'default_sale_order_ids': [(6, 0, self.ids)],
'default_invoice_ids': [(6, 0, invoice_ids.ids)],
- 'default_uang_masuk': total_so,
+ 'default_uang_masuk': total_uang_masuk,
'default_ongkir': delivery_total,
'default_bank': '',
'default_account_name': '',
@@ -3259,11 +3312,6 @@ class SaleOrder(models.Model):
}
}
- @api.depends('refund_ids')
- def _compute_has_refund(self):
- for so in self:
- so.has_refund = bool(so.refund_ids)
-
def action_view_related_refunds(self):
self.ensure_one()
return {
diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml
index 27c5feec..dd47c2ab 100644
--- a/indoteknik_custom/views/refund_sale_order.xml
+++ b/indoteknik_custom/views/refund_sale_order.xml
@@ -14,6 +14,7 @@
<field name="ongkir" readonly="1"/>
<field name="total_invoice" readonly="1"/>
<field name="amount_refund" readonly="1"/>
+ <field name="remaining_refundable" readonly="1" optional="hide"/>
<field name="status"
decoration-info="status == 'draft'"
decoration-danger="status == 'reject'"
@@ -117,11 +118,13 @@
<field name="note_refund" attrs="{'readonly': [('is_locked', '=', True)]}"/>
</group>
<group>
- <field name="uang_masuk" attrs="{'readonly': ['|', ('is_locked', '=', True), ('refund_type', '=', 'barang_kosong_sebagian')]}"/>
+ <field name="uang_masuk" readonly="1"/>
<field name="total_invoice" readonly="1"/>
<field name="ongkir" attrs="{'readonly': [('is_locked', '=', True)]}"/>
<field name="amount_refund" attrs="{'readonly': [('is_locked', '=', True)]}"/>
<field name="amount_refund_text" readonly="1"/>
+ <field name="sale_order_count" invisible="1"/>
+ <field name="remaining_refundable" readonly="1" attrs="{'invisible': [('sale_order_count', '>', 1)]}"/>
<field name="uang_masuk_type" required="1" attrs="{'readonly': [('is_locked', '=', True)]}"/>
<field name="bukti_uang_masuk_image" widget="image"
attrs="{'invisible': [('uang_masuk_type', '=', 'pdf')], 'readonly': [('is_locked', '=', True)]}"/>
@@ -133,7 +136,8 @@
<notebook>
<page string="Produk Line">
<field name="line_ids" attrs="{'readonly': [('is_locked', '=', True)]}">
- <tree editable="bottom">
+ <tree editable="bottom" create="0" delete="1">
+ <field name="product_from"/>
<field name="product_id"/>
<field name="quantity"/>
<field name="reason"/>
@@ -168,6 +172,38 @@
</group>
</group>
</page>
+ <page string="Sales Order Lines">
+ <field name="so_order_line_ids" nolabel="1" readonly="1">
+ <tree>
+ <field name="order_id"/>
+ <field name="product_id"/>
+ <field name="purchase_price"/>
+ <field name="product_uom_qty"/>
+ <field name="price_unit"/>
+ <field name="tax_id" widget="many2many_tags"/>
+ <field name="discount"/>
+ <field name="price_subtotal"/>
+ <field name="item_percent_margin"/>
+ <field name="item_percent_margin_before"/>
+ </tree>
+ </field>
+ <group class="oe_subtotal_footer oe_right" colspan="2" name="refund_total">
+ <field name="amount_untaxed" widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1"/>
+ <field name="amount_tax" widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1"/>
+ <div class="oe_subtotal_footer_separator oe_inline o_td_label">
+ <label for="amount_total"/>
+ </div>
+ <field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator"
+ widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1"/>
+ <field name="delivery_amt" widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1"/>
+ <div class="oe_subtotal_footer_separator oe_inline o_td_label">
+ <label for="grand_total"/>
+ </div>
+ <field name="grand_total" nolabel="1" class="oe_subtotal_footer_separator"
+ widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1"/>
+ <field name="total_margin" widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1"/>
+ </group>
+ </page>
<page string="Cancel Reason" attrs="{'invisible': [('status', '=', 'refund')]}">
<group>
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index 1d51fd69..8f8e4288 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -39,8 +39,7 @@
<button name="button_refund"
type="object"
string="Refund"
- class="btn-primary"
- attrs="{'invisible': [('has_refund', '=', 'True')]}" />
+ class="btn-primary" />
</xpath>
<div class="oe_button_box" name="button_box">
<field name="advance_payment_move_ids" invisible="1"/>
@@ -177,7 +176,6 @@
<field name="expected_ready_to_ship"/>
<field name="eta_date_start"/>
<field name="eta_date" readonly="1"/>
- <field name="has_refund" readonly="1"/>
</group>
<group string="Return Doc">
<field name="ccm_id" readonly="1"/>