summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2025-05-14 10:21:18 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2025-05-14 10:21:18 +0700
commitf9240997e9796a1149a1f8bddc48fa1ebbbbf873 (patch)
tree98f106aa0996f14f2ee0001d6c550a2b054efd5f /indoteknik_custom/models
parent509a771b8ba6122cc308323dbe90ff4a35e4fc72 (diff)
parent285fa052180ca0ae11e0431d5cf95e795008cae9 (diff)
Merge branch 'odoo-backup' of bitbucket.org:altafixco/indoteknik-addons into odoo-backup
Diffstat (limited to 'indoteknik_custom/models')
-rwxr-xr-xindoteknik_custom/models/sale_order.py466
1 files changed, 259 insertions, 207 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 0d4fc6c3..99aa8053 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -9,6 +9,7 @@ from collections import defaultdict
_logger = logging.getLogger(__name__)
+
class CancelReasonOrder(models.TransientModel):
_name = 'cancel.reason.order'
_description = 'Wizard for Cancel Reason order'
@@ -44,7 +45,7 @@ class CancelReasonOrder(models.TransientModel):
raise UserError('Attachment bukti wajib disertakan')
order.write({'attachment_bukti': self.attachment_bukti})
order.message_post(body='Attachment Bukti Cancel',
- attachment_ids=[self.attachment_bukti.id])
+ attachment_ids=[self.attachment_bukti.id])
if self.reason_cancel == 'ganti_quotation':
if self.nomor_so_pengganti:
order.write({'nomor_so_pengganti': self.nomor_so_pengganti})
@@ -53,7 +54,8 @@ class CancelReasonOrder(models.TransientModel):
order.confirm_cancel_order()
return {'type': 'ir.actions.act_window_close'}
-
+
+
class ShippingOption(models.Model):
_name = "shipping.option"
_description = "Shipping Option"
@@ -64,6 +66,7 @@ class ShippingOption(models.Model):
etd = fields.Char(string="Estimated Delivery Time")
sale_order_id = fields.Many2one('sale.order', string="Sale Order", ondelete="cascade")
+
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
@@ -73,7 +76,7 @@ class SaleOrderLine(models.Model):
if line.order_id:
now = fields.Datetime.now()
- initial_reason="Product Rejected"
+ initial_reason = "Product Rejected"
# Buat lognote untuk product yang di delete
log_note = (f"<li>Product '{line.product_id.name}' rejected. </li>"
@@ -113,10 +116,12 @@ class SaleOrderLine(models.Model):
return result
+
class SaleOrder(models.Model):
_inherit = "sale.order"
- ongkir_ke_xpdc = fields.Float(string='Ongkir ke Ekspedisi', help='Biaya ongkir ekspedisi', copy=False, index=True, tracking=3)
+ ongkir_ke_xpdc = fields.Float(string='Ongkir ke Ekspedisi', help='Biaya ongkir ekspedisi', copy=False, index=True,
+ tracking=3)
metode_kirim_ke_xpdc = fields.Selection([
('indoteknik_deliv', 'Indoteknik Delivery'),
@@ -127,22 +132,31 @@ class SaleOrder(models.Model):
('other', 'Other'),
], string='Metode Kirim Ke Ekspedisi', copy=False, index=True, tracking=3)
+ notes = fields.Text(string="Notes", tracking=3)
koli_lines = fields.One2many('sales.order.koli', 'sale_order_id', string='Sales Order Koli', auto_join=True)
fulfillment_line_v2 = fields.One2many('sales.order.fulfillment.v2', 'sale_order_id', string='Fullfillment2')
fullfillment_line = fields.One2many('sales.order.fullfillment', 'sales_order_id', string='Fullfillment')
reject_line = fields.One2many('sales.order.reject', 'sale_order_id', string='Reject Lines')
- order_sales_match_line = fields.One2many('sales.order.purchase.match', 'sales_order_id', string='Purchase Match Lines', states={'cancel': [('readonly', True)], 'done': [('readonly', True)]}, copy=True)
- total_margin = fields.Float('Total Margin', compute='_compute_total_margin', help="Total Margin in Sales Order Header")
- total_before_margin = fields.Float('Total Before Margin', compute='_compute_total_before_margin', help="Total Margin in Sales Order Header")
- total_percent_margin = fields.Float('Total Percent Margin', compute='_compute_total_percent_margin', help="Total % Margin in Sales Order Header")
- total_margin_excl_third_party = fields.Float('Before Margin', help="Before Margin in Sales Order Header", compute='_compute_total_margin_excl_third_party')
+ order_sales_match_line = fields.One2many('sales.order.purchase.match', 'sales_order_id',
+ string='Purchase Match Lines',
+ states={'cancel': [('readonly', True)], 'done': [('readonly', True)]},
+ copy=True)
+ total_margin = fields.Float('Total Margin', compute='_compute_total_margin',
+ help="Total Margin in Sales Order Header")
+ total_before_margin = fields.Float('Total Before Margin', compute='_compute_total_before_margin',
+ help="Total Margin in Sales Order Header")
+ total_percent_margin = fields.Float('Total Percent Margin', compute='_compute_total_percent_margin',
+ help="Total % Margin in Sales Order Header")
+ total_margin_excl_third_party = fields.Float('Before Margin', help="Before Margin in Sales Order Header",
+ compute='_compute_total_margin_excl_third_party')
approval_status = fields.Selection([
('pengajuan1', 'Approval Manager'),
('pengajuan2', 'Approval Pimpinan'),
('approved', 'Approved'),
], string='Approval Status', readonly=True, copy=False, index=True, tracking=3)
carrier_id = fields.Many2one('delivery.carrier', string='Shipping Method', tracking=3)
- have_visit_service = fields.Boolean(string='Have Visit Service', compute='_have_visit_service', help='To compute is customer get visit service')
+ have_visit_service = fields.Boolean(string='Have Visit Service', compute='_have_visit_service',
+ help='To compute is customer get visit service')
delivery_amt = fields.Float(string='Delivery Amt', copy=False)
shipping_cost_covered = fields.Selection([
('indoteknik', 'Indoteknik'),
@@ -152,7 +166,8 @@ class SaleOrder(models.Model):
('indoteknik', 'Indoteknik'),
('customer', 'Customer')
], string='Shipping Paid by', help='Siapa yang talangin dulu Biaya ekspedisi-nya?', copy=False, tracking=3)
- sales_tax_id = fields.Many2one('account.tax', string='Tax', domain=['|', ('active', '=', False), ('active', '=', True)])
+ sales_tax_id = fields.Many2one('account.tax', string='Tax',
+ domain=['|', ('active', '=', False), ('active', '=', True)])
have_outstanding_invoice = fields.Boolean('Have Outstanding Invoice', compute='_have_outstanding_invoice')
have_outstanding_picking = fields.Boolean('Have Outstanding Picking', compute='_have_outstanding_picking')
have_outstanding_po = fields.Boolean('Have Outstanding PO', compute='_have_outstanding_po')
@@ -173,9 +188,14 @@ class SaleOrder(models.Model):
('sebagian', 'Sebagian Diproses'),
('menunggu', 'Menunggu Diproses'),
], copy=False)
- partner_purchase_order_name = fields.Char(string='Nama PO Customer', copy=False, help="Nama purchase order customer, diisi oleh customer melalui website.", tracking=3)
- partner_purchase_order_description = fields.Text(string='Keterangan PO Customer', copy=False, help="Keterangan purchase order customer, diisi oleh customer melalui website.", tracking=3)
- partner_purchase_order_file = fields.Binary(string='File PO Customer', copy=False, help="File purchase order customer, diisi oleh customer melalui website.")
+ partner_purchase_order_name = fields.Char(string='Nama PO Customer', copy=False,
+ help="Nama purchase order customer, diisi oleh customer melalui website.",
+ tracking=3)
+ partner_purchase_order_description = fields.Text(string='Keterangan PO Customer', copy=False,
+ help="Keterangan purchase order customer, diisi oleh customer melalui website.",
+ tracking=3)
+ partner_purchase_order_file = fields.Binary(string='File PO Customer', copy=False,
+ help="File purchase order customer, diisi oleh customer melalui website.")
payment_status = fields.Selection([
('pending', 'Pending'),
('capture', 'Capture'),
@@ -189,17 +209,22 @@ class SaleOrder(models.Model):
('partial_refund', 'Partial Refund'),
('partial_chargeback', 'Partial Chargeback'),
('authorize', 'Authorize'),
- ], tracking=True, string='Payment Status', help='Payment Gateway Status / Midtrans / Web, https://docs.midtrans.com/en/after-payment/status-cycle')
- date_doc_kirim = fields.Datetime(string='Tanggal Kirim di SJ', help="Tanggal Kirim di cetakan SJ yang terakhir, tidak berpengaruh ke Accounting")
+ ], tracking=True, string='Payment Status',
+ help='Payment Gateway Status / Midtrans / Web, https://docs.midtrans.com/en/after-payment/status-cycle')
+ date_doc_kirim = fields.Datetime(string='Tanggal Kirim di SJ',
+ help="Tanggal Kirim di cetakan SJ yang terakhir, tidak berpengaruh ke Accounting")
payment_type = fields.Char(string='Payment Type', help='Jenis pembayaran dengan Midtrans')
gross_amount = fields.Float(string='Gross Amount', help='Jumlah pembayaran yang dilakukan dengan Midtrans')
notification = fields.Char(string='Notification', help='Dapat membantu error dari approval')
delivery_service_type = fields.Char(string='Delivery Service Type', help='data dari rajaongkir')
- grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total')
- payment_link_midtrans = fields.Char(string='Payment Link', help='Url payment yg digenerate oleh midtrans, harap diserahkan ke customer agar dapat dilakukan pembayaran secara mandiri')
+ grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery',
+ compute='_compute_grand_total')
+ payment_link_midtrans = fields.Char(string='Payment Link',
+ help='Url payment yg digenerate oleh midtrans, harap diserahkan ke customer agar dapat dilakukan pembayaran secara mandiri')
payment_qr_code = fields.Binary("Payment QR Code")
- due_id = fields.Many2one('due.extension', string="Due Extension", readonly=True, tracking=True)
- vendor_approval_id = fields.Many2many('vendor.approval', string="Vendor Approval", readonly=True, tracking=True, copy=False)
+ due_id = fields.Many2one('due.extension', string="Due Extension", readonly=True, tracking=True)
+ vendor_approval_id = fields.Many2many('vendor.approval', string="Vendor Approval", readonly=True, tracking=True,
+ copy=False)
customer_type = fields.Selection([
('pkp', 'PKP'),
('nonpkp', 'Non PKP')
@@ -239,8 +264,10 @@ class SaleOrder(models.Model):
use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False)
unreserve_id = fields.Many2one('stock.picking', 'Unreserve Picking')
voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher Shipping', copy=False)
- margin_after_delivery_purchase = fields.Float(string='Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase')
- percent_margin_after_delivery_purchase = fields.Float(string='% Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase')
+ margin_after_delivery_purchase = fields.Float(string='Margin After Delivery Purchase',
+ compute='_compute_margin_after_delivery_purchase')
+ percent_margin_after_delivery_purchase = fields.Float(string='% Margin After Delivery Purchase',
+ compute='_compute_margin_after_delivery_purchase')
purchase_delivery_amt = fields.Float(string='Purchase Delivery Amount', compute='_compute_purchase_delivery_amount')
type_promotion = fields.Char(string='Type Promotion', compute='_compute_type_promotion')
partner_invoice_id = fields.Many2one(
@@ -254,11 +281,11 @@ class SaleOrder(models.Model):
'res.partner', string='Delivery Address', readonly=True, required=True,
states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]},
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True)
-
+
payment_term_id = fields.Many2one(
'account.payment.term', string='Payment Terms', check_company=True, # Unrequired company
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True)
-
+
total_weight = fields.Float(string='Total Weight', compute='_compute_total_weight')
pareto_status = fields.Selection([
('PR', 'Pareto Repeating'),
@@ -275,7 +302,7 @@ class SaleOrder(models.Model):
copy=False
)
shipping_method_picking = fields.Char(string='Shipping Method Picking', compute='_compute_shipping_method_picking')
-
+
reason_cancel = fields.Selection([
('harga_terlalu_mahal', 'Harga barang terlalu mahal'),
('harga_web_tidak_valid', 'Harga web tidak valid'),
@@ -296,7 +323,8 @@ class SaleOrder(models.Model):
string="Attachment Bukti Cancel", readonly=False,
)
nomor_so_pengganti = fields.Char(string='Nomor SO Pengganti', copy=False, tracking=3)
- shipping_option_id = fields.Many2one("shipping.option", string="Selected Shipping Option", domain="['|', ('sale_order_id', '=', False), ('sale_order_id', '=', id)]")
+ shipping_option_id = fields.Many2one("shipping.option", string="Selected Shipping Option",
+ domain="['|', ('sale_order_id', '=', False), ('sale_order_id', '=', id)]")
hold_outgoing = fields.Boolean('Hold Outgoing SO', tracking=3)
state_ask_cancel = fields.Selection([
('hold', 'Hold'),
@@ -355,7 +383,7 @@ class SaleOrder(models.Model):
tax_sets.add(tax_ids)
if len(tax_sets) > 1:
raise ValidationError("Semua produk dalam Sales Order harus memiliki kombinasi pajak yang sama.")
-
+
# @api.constrains('fee_third_party', 'delivery_amt', 'biaya_lain_lain')
# def _check_total_margin_excl_third_party(self):
# for rec in self:
@@ -403,14 +431,14 @@ class SaleOrder(models.Model):
def action_indoteknik_estimate_shipping(self):
if not self.real_shipping_id.kota_id.is_jabodetabek:
raise UserError('Estimasi ongkir hanya bisa dilakukan di kota Jabodetabek')
-
+
total_weight = 0
missing_weight_products = []
for line in self.order_line:
if line.weight > 0:
total_weight += line.weight * line.product_uom_qty
- line.product_id.weight = line.weight
+ line.product_id.weight = line.weight
else:
missing_weight_products.append(line.product_id.name)
@@ -420,10 +448,10 @@ class SaleOrder(models.Model):
if total_weight == 0:
raise UserError("Tidak dapat mengestimasi ongkir tanpa berat yang valid.")
-
+
if total_weight < 10:
total_weight = 10
-
+
self.delivery_amt = total_weight * 3000
shipping_option = self.env["shipping.option"].create({
@@ -456,7 +484,7 @@ class SaleOrder(models.Model):
for line in self.order_line:
if line.weight > 0:
total_weight += line.weight * line.product_uom_qty
- line.product_id.weight = line.weight
+ line.product_id.weight = line.weight
else:
missing_weight_products.append(line.product_id.name)
@@ -481,11 +509,11 @@ class SaleOrder(models.Model):
etd = cost_detail['cost'][0]['etd']
value = cost_detail['cost'][0]['value']
shipping_options.append((service, description, etd, value, courier['code']))
-
+
self.env["shipping.option"].search([('sale_order_id', '=', self.id)]).unlink()
_logger.info(f"Shipping options: {shipping_options}")
-
+
for service, description, etd, value, provider in shipping_options:
self.env["shipping.option"].create({
"name": service,
@@ -495,22 +523,20 @@ class SaleOrder(models.Model):
"sale_order_id": self.id,
})
-
self.shipping_option_id = self.env["shipping.option"].search([('sale_order_id', '=', self.id)], limit=1).id
_logger.info(f"Shipping option SO ID: {self.shipping_option_id}")
self.message_post(
body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}<br/>Detail Lain:<br/>"
- f"{'<br/>'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}",
+ f"{'<br/>'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}",
message_type="comment"
)
-
+
# self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}<br/>Detail Lain:<br/>{'<br/>'.join([f'Service: {s[0]}, Description: {s[1]}, ETD: {s[2]} hari, Cost: Rp {s[3]}' for s in shipping_options])}", message_type="comment")
else:
raise UserError("Gagal mendapatkan estimasi ongkir.")
-
def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id):
url = 'https://pro.rajaongkir.com/api/cost'
@@ -532,7 +558,7 @@ class SaleOrder(models.Model):
if response.status_code == 200:
return response.json()
return None
-
+
def _normalize_city_name(self, city_name):
city_name = city_name.lower()
@@ -552,7 +578,7 @@ class SaleOrder(models.Model):
}
normalized_city_name = self._normalize_city_name(city_name)
-
+
response = requests.get(url, headers=headers)
if response.status_code == 200:
city_data = response.json()
@@ -566,7 +592,7 @@ class SaleOrder(models.Model):
headers = {
'key': '9b1310f644056d84d60b0af6bb21611a',
}
-
+
response = requests.get(url, headers=headers)
if response.status_code == 200:
subdistrict_data = response.json()
@@ -578,15 +604,15 @@ class SaleOrder(models.Model):
return subdistrict['subdistrict_id']
return None
-
def _compute_type_promotion(self):
for rec in self:
promotion_types = []
for promotion in rec.order_promotion_ids:
for line_program in promotion.program_line_id:
if line_program.promotion_type:
- promotion_types.append(dict(line_program._fields['promotion_type'].selection).get(line_program.promotion_type))
-
+ promotion_types.append(
+ dict(line_program._fields['promotion_type'].selection).get(line_program.promotion_type))
+
rec.type_promotion = ', '.join(sorted(set(promotion_types)))
def _compute_purchase_delivery_amount(self):
@@ -610,11 +636,14 @@ class SaleOrder(models.Model):
delivery_amt = order.delivery_amt
else:
delivery_amt = 0
- order.percent_margin_after_delivery_purchase = round((order.margin_after_delivery_purchase / (order.amount_untaxed-delivery_amt-order.fee_third_party-order.biaya_lain_lain)) * 100, 2)
+ order.percent_margin_after_delivery_purchase = round((order.margin_after_delivery_purchase / (
+ order.amount_untaxed - delivery_amt - order.fee_third_party - order.biaya_lain_lain)) * 100, 2)
def _compute_date_kirim(self):
for rec in self:
- picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel']), ('name', 'not ilike', 'BU/PICK/%')], order='date_doc_kirim desc', limit=1)
+ picking = self.env['stock.picking'].search(
+ [('sale_id', '=', rec.id), ('state', 'not in', ['cancel']), ('name', 'not ilike', 'BU/PICK/%')],
+ order='date_doc_kirim desc', limit=1)
rec.date_kirim_ril = picking.date_doc_kirim
rec.date_status_done = picking.date_done
rec.date_driver_arrival = picking.driver_arrival_date
@@ -626,54 +655,55 @@ class SaleOrder(models.Model):
'so_ids': [x.id for x in self]
}
return action
-
+
def _compute_fullfillment(self):
for rec in self:
- # rec.fullfillment_line.unlink()
- #
- # for line in rec.order_line:
- # line._compute_reserved_from()
+ # rec.fullfillment_line.unlink()
+ #
+ # for line in rec.order_line:
+ # line._compute_reserved_from()
rec.compute_fullfillment = True
@api.depends('date_order', 'estimated_arrival_days', 'state', 'estimated_arrival_days_start')
def _compute_eta_date(self):
- current_date = datetime.now().date()
- for rec in self:
- if rec.date_order and rec.state not in ['cancel'] and rec.estimated_arrival_days and rec.estimated_arrival_days_start:
+ current_date = datetime.now().date()
+ for rec in self:
+ if rec.date_order and rec.state not in [
+ 'cancel'] and rec.estimated_arrival_days and rec.estimated_arrival_days_start:
rec.eta_date = current_date + timedelta(days=rec.estimated_arrival_days)
rec.eta_date_start = current_date + timedelta(days=rec.estimated_arrival_days_start)
else:
rec.eta_date = False
rec.eta_date_start = False
-
-
- def get_days_until_next_business_day(self,start_date=None, *args, **kwargs):
+
+ def get_days_until_next_business_day(self, start_date=None, *args, **kwargs):
today = start_date or datetime.today().date()
offset = 0 # Counter jumlah hari yang ditambahkan
holiday = self.env['hr.public.holiday']
- while True :
+ while True:
today += timedelta(days=1)
offset += 1
-
+
if today.weekday() >= 5:
continue
is_holiday = holiday.search([("start_date", "=", today)])
if is_holiday:
continue
-
+
break
return offset
-
+
def calculate_sla_by_vendor(self, products):
product_ids = products.mapped('product_id.id') # Kumpulkan semua ID produk
include_instant = True # Default True, tetapi bisa menjadi False
# Cek apakah SEMUA produk memiliki qty_free_bandengan >= qty_needed
- all_fast_products = all(product.product_id.qty_free_bandengan >= product.product_uom_qty for product in products)
+ all_fast_products = all(
+ product.product_id.qty_free_bandengan >= product.product_uom_qty for product in products)
if all_fast_products:
return {'slatime': 1, 'include_instant': include_instant}
@@ -683,7 +713,7 @@ class SaleOrder(models.Model):
('is_winner', '=', True)
])
- max_slatime = 1
+ max_slatime = 1
for vendor in vendors:
vendor_sla = self.env['vendor.sla'].search([('id_vendor', '=', vendor.vendor_id.id)], limit=1)
@@ -692,26 +722,26 @@ class SaleOrder(models.Model):
if vendor_sla.unit == 'hari':
vendor_duration = vendor_sla.duration * 24 * 60
include_instant = False
- else :
+ else:
vendor_duration = vendor_sla.duration * 60
include_instant = True
-
+
estimation_sla = (1 * 24 * 60) + vendor_duration
estimation_sla_days = estimation_sla / (24 * 60)
slatime = math.ceil(estimation_sla_days)
-
+
max_slatime = max(max_slatime, slatime)
return {'slatime': max_slatime, 'include_instant': include_instant}
-
+
def _calculate_etrts_date(self):
for rec in self:
if not rec.date_order:
rec.expected_ready_to_ship = False
return
-
+
current_date = datetime.now().date()
-
+
max_slatime = 1 # Default SLA jika tidak ada
slatime = self.calculate_sla_by_vendor(rec.order_line)
max_slatime = max(max_slatime, slatime['slatime'])
@@ -719,29 +749,28 @@ class SaleOrder(models.Model):
sum_days = max_slatime + self.get_days_until_next_business_day(current_date) - 1
if not rec.estimated_arrival_days:
rec.estimated_arrival_days = sum_days
-
+
eta_date = current_date + timedelta(days=sum_days)
rec.commitment_date = eta_date
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
+
+ @api.depends("order_line.product_id", "date_order")
+ def _compute_etrts_date(self): # Function to calculate Estimated Ready To Ship Date
self._calculate_etrts_date()
-
-
+
def _validate_expected_ready_ship_date(self):
for rec in self:
if rec.expected_ready_to_ship and rec.commitment_date:
current_date = datetime.now().date()
# Hanya membandingkan tanggal saja, tanpa jam
expected_date = rec.expected_ready_to_ship.date()
-
+
max_slatime = 1 # Default SLA jika tidak ada
slatime = self.calculate_sla_by_vendor(rec.order_line)
max_slatime = max(max_slatime, slatime['slatime'])
sum_days = max_slatime + self.get_days_until_next_business_day(current_date) - 1
eta_minimum = current_date + timedelta(days=sum_days)
-
+
if expected_date < eta_minimum:
rec.expected_ready_to_ship = eta_minimum
raise ValidationError(
@@ -750,16 +779,16 @@ class SaleOrder(models.Model):
)
else:
rec.commitment_date = rec.expected_ready_to_ship
-
-
- @api.onchange('expected_ready_to_ship') #Hangle Onchange form Expected Ready to Ship
+
+ @api.onchange('expected_ready_to_ship') # Hangle Onchange form Expected Ready to Ship
def _onchange_expected_ready_ship_date(self):
self._validate_expected_ready_ship_date()
def _set_etrts_date(self):
for order in self:
if order.state in ('done', 'cancel', 'sale'):
- raise UserError(_("You cannot change the Estimated Ready To Ship Date on a done, sale or cancelled order."))
+ raise UserError(
+ _("You cannot change the Estimated Ready To Ship Date on a done, sale or cancelled order."))
# order.move_lines.write({'estimated_ready_ship_date': order.estimated_ready_ship_date})
def _prepare_invoice(self):
@@ -771,10 +800,12 @@ class SaleOrder(models.Model):
self.ensure_one()
journal = self.env['account.move'].with_context(default_move_type='out_invoice')._get_default_journal()
if not journal:
- raise UserError(_('Please define an accounting sales journal for the company %s (%s).') % (self.company_id.name, self.company_id.id))
+ raise UserError(
+ _('Please define an accounting sales journal for the company %s (%s).') % (self.company_id.name,
+ self.company_id.id))
parent_id = self.partner_id.parent_id
- parent_id = parent_id if parent_id else self.partner_id
+ parent_id = parent_id if parent_id else self.partner_id
invoice_vals = {
'ref': self.client_order_ref or '',
@@ -791,7 +822,8 @@ class SaleOrder(models.Model):
'partner_id': parent_id.id,
'partner_shipping_id': parent_id.id,
'real_invoice_id': self.real_invoice_id.id,
- 'fiscal_position_id': (self.fiscal_position_id or self.fiscal_position_id.get_fiscal_position(self.partner_invoice_id.id)).id,
+ 'fiscal_position_id': (self.fiscal_position_id or self.fiscal_position_id.get_fiscal_position(
+ self.partner_invoice_id.id)).id,
'partner_bank_id': self.company_id.partner_id.bank_ids[:1].id,
'journal_id': journal.id, # company comes from the journal
'invoice_origin': self.name,
@@ -807,10 +839,10 @@ class SaleOrder(models.Model):
def _validate_email(self):
rule_regex = self.env['ir.config_parameter'].sudo().get_param('sale.order.validate_email') or ''
pattern = rf'^{rule_regex}$'
-
+
if self.email and not re.match(pattern, self.email):
raise UserError('Email yang anda input kurang valid')
-
+
# @api.constrains('delivery_amt', 'carrier_id', 'shipping_cost_covered')
def _validate_delivery_amt(self):
is_indoteknik = self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik'
@@ -822,13 +854,14 @@ class SaleOrder(models.Model):
raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum diisi.')
else:
raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum diisi.')
-
+
if self.delivery_amt < 100:
if self.carrier_id.id == 1:
- raise UserError('Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi tarif minimum.')
+ raise UserError(
+ 'Untuk Kurir Indoteknik Delivery, estimasi ongkos kirim belum memenuhi tarif minimum.')
else:
- raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi tarif minimum.')
-
+ raise UserError(
+ 'Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi tarif minimum.')
# if self.delivery_amt < 5000:
# if (self.carrier_id.id == 1 or self.shipping_cost_covered == 'indoteknik') and not self.env.context.get('active_id', []):
@@ -837,7 +870,6 @@ class SaleOrder(models.Model):
# else:
# raise UserError('Untuk Shipping Covered Indoteknik, estimasi ongkos kirim belum memenuhi jumlah minimum.')
-
def override_allow_create_invoice(self):
if not self.env.user.is_accounting:
raise UserError('Hanya Finance Accounting yang dapat klik tombol ini')
@@ -878,14 +910,14 @@ class SaleOrder(models.Model):
'sale_ids': [x.id for x in self]
}
return action
-
+
def open_form_multi_update_state(self):
action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_quotation_so_multi_update')
action['context'] = {
'quotation_ids': [x.id for x in self]
}
return action
-
+
def action_multi_update_invoice_status(self):
for sale in self:
sale.update({
@@ -898,7 +930,7 @@ class SaleOrder(models.Model):
for line in order.order_line:
total += line.vendor_subtotal
order.purchase_total = total
-
+
def check_data_real_delivery_address(self):
real_delivery_address = self.real_shipping_id
@@ -918,8 +950,8 @@ class SaleOrder(models.Model):
def generate_payment_link_midtrans_sales_order(self):
# midtrans_url = 'https://app.sandbox.midtrans.com/snap/v1/transactions' # dev - sandbox
# midtrans_auth = 'Basic U0ItTWlkLXNlcnZlci1uLVY3ZDJjMlpCMFNWRUQyOU95Q1dWWXA6' # dev - sandbox
- midtrans_url = 'https://app.midtrans.com/snap/v1/transactions' # production
- midtrans_auth = 'Basic TWlkLXNlcnZlci1SbGMxZ2gzWGpSVW5scl9JblZzTV9OTnU6' # production
+ midtrans_url = 'https://app.midtrans.com/snap/v1/transactions' # production
+ midtrans_auth = 'Basic TWlkLXNlcnZlci1SbGMxZ2gzWGpSVW5scl9JblZzTV9OTnU6' # production
so_number = self.name
so_number = so_number.replace('/', '-')
so_grandtotal = math.floor(self.grand_total)
@@ -934,7 +966,8 @@ class SaleOrder(models.Model):
if check_response.status_code == 200:
status_response = check_response.json()
- if status_response.get('transaction_status') == 'expire' or status_response.get('transaction_status') == 'cancel':
+ if status_response.get('transaction_status') == 'expire' or status_response.get(
+ 'transaction_status') == 'cancel':
so_number = so_number + '-cpl'
json_data = {
@@ -982,8 +1015,7 @@ class SaleOrder(models.Model):
if line.product_id.type == 'product':
line_no += 1
line.line_no = line_no
-
-
+
def write(self, vals):
if 'carrier_id' in vals:
for picking in self.picking_ids:
@@ -996,7 +1028,7 @@ class SaleOrder(models.Model):
('state', 'in', so_state),
('so_status', '!=', 'terproses'),
])
-
+
for sale in sales:
picking_states = ['draft', 'assigned', 'confirmed', 'waiting']
have_outstanding_pick = any(x.state in picking_states for x in sale.picking_ids)
@@ -1010,16 +1042,16 @@ class SaleOrder(models.Model):
sale.so_status = 'terproses'
else:
sale.so_status = 'menunggu'
-
+
for picking in sale.picking_ids:
sum_qty_pick = sum(move_line.product_uom_qty for move_line in picking.move_ids_without_package)
sum_qty_reserved = sum(move_line.product_uom_qty for move_line in picking.move_line_ids_without_package)
if picking.state == 'done':
continue
- elif sum_qty_pick == sum_qty_reserved and not picking.date_reserved:# baru ke reserved
+ elif sum_qty_pick == sum_qty_reserved and not picking.date_reserved: # baru ke reserved
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
picking.date_reserved = current_time
- elif sum_qty_pick == sum_qty_reserved:# sudah ada data reserved
+ elif sum_qty_pick == sum_qty_reserved: # sudah ada data reserved
picking.date_reserved = picking.date_reserved
else:
picking.date_reserved = ''
@@ -1054,7 +1086,7 @@ class SaleOrder(models.Model):
@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
+ parent_id = parent_id if parent_id else self.partner_id
self.npwp = parent_id.npwp
self.sppkp = parent_id.sppkp
@@ -1062,13 +1094,13 @@ class SaleOrder(models.Model):
self.email = parent_id.email
self.pareto_status = parent_id.pareto_status
self.user_id = parent_id.user_id
-
+
@api.onchange('partner_id')
def onchange_partner_id(self):
# INHERIT
result = super(SaleOrder, self).onchange_partner_id()
parent_id = self.partner_id.parent_id
- parent_id = parent_id if parent_id else self.partner_id
+ parent_id = parent_id if parent_id else self.partner_id
self.partner_invoice_id = parent_id
return result
@@ -1101,16 +1133,16 @@ class SaleOrder(models.Model):
minimum_amount = 20000000
for order in self:
order.have_visit_service = self.amount_total > minimum_amount
-
+
def _get_helper_ids(self):
helper_ids_str = self.env['ir.config_parameter'].sudo().get_param('sale.order.user_helper_ids')
return helper_ids_str.split(', ')
-
+
def write(self, values):
helper_ids = self._get_helper_ids()
if str(self.env.user.id) in helper_ids:
values['helper_by_id'] = self.env.user.id
-
+
return super(SaleOrder, self).write(values)
def check_due(self):
@@ -1128,21 +1160,21 @@ class SaleOrder(models.Model):
def _validate_order(self):
if self.payment_term_id.id == 31 and self.total_percent_margin < 25:
raise UserError("Jika ingin menggunakan Tempo 90 Hari maka margin harus di atas 25%")
-
- if self.warehouse_id.id != 8 and self.warehouse_id.id != 10: #GD Bandengan
+
+ if self.warehouse_id.id != 8 and self.warehouse_id.id != 10: # GD Bandengan
raise UserError('Gudang harus Bandengan')
-
+
if self.state not in ['draft', 'sent']:
raise UserError("Status harus draft atau sent")
-
+
self._validate_npwp()
-
+
def _validate_npwp(self):
num_digits = sum(c.isdigit() for c in self.npwp)
if num_digits < 10:
raise UserError("NPWP harus memiliki minimal 10 digit")
-
+
# pattern = r'^\d{10,}$'
# return re.match(pattern, self.npwp) is not None
@@ -1170,7 +1202,8 @@ class SaleOrder(models.Model):
if (partner.customer_type == 'pkp' or order.customer_type == 'pkp') and order.sppkp != partner.sppkp:
raise UserError("SPPKP berbeda pada Master Data Customer")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
- raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ raise UserError(
+ "Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
if not order.user_id.active:
raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact")
@@ -1178,20 +1211,23 @@ class SaleOrder(models.Model):
for order in self:
for line in order.order_line:
if 'bom-it' in line.name.lower() or 'bom' in line.product_id.default_code.lower() if line.product_id.default_code else False:
- search_bom = self.env['mrp.production'].search([('product_id', '=', line.product_id.id)],order='name desc')
+ search_bom = self.env['mrp.production'].search([('product_id', '=', line.product_id.id)],
+ order='name desc')
if search_bom:
confirmed_bom = search_bom.filtered(lambda x: x.state == 'confirmed')
if not confirmed_bom:
- raise UserError("Product BOM belum dikonfirmasi di Manufacturing Orders. Silakan hubungi MD.")
+ raise UserError(
+ "Product BOM belum dikonfirmasi di Manufacturing Orders. Silakan hubungi MD.")
else:
raise UserError("Product BOM tidak di temukan di manufacturing orders, silahkan hubungi MD")
-
+
def check_duplicate_product(self):
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)])
- if len(search_product) > 1:
- raise UserError("Terdapat DUPLIKASI data pada Product {}".format(line.product_id.display_name))
+ search_product = self.env['sale.order.line'].search(
+ [('product_id', '=', line.product_id.id), ('order_id', '=', order.id)])
+ if len(search_product) > 1:
+ raise UserError("Terdapat DUPLIKASI data pada Product {}".format(line.product_id.display_name))
def sale_order_approve(self):
self.check_duplicate_product()
@@ -1214,11 +1250,13 @@ class SaleOrder(models.Model):
SYSTEM_UID = 25
FROM_WEBSITE = order.create_uid.id == SYSTEM_UID
- if FROM_WEBSITE and main_parent.use_so_approval and order.web_approval not in ['cust_procurement','cust_director']:
+ if FROM_WEBSITE and main_parent.use_so_approval and order.web_approval not in ['cust_procurement',
+ 'cust_director']:
raise UserError("This order not yet approved by customer procurement or director")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
- raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ raise UserError(
+ "Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
if not order.commitment_date and order.create_date > datetime(2024, 9, 12):
raise UserError("Expected Delivery Date kosong, wajib diisi")
@@ -1227,7 +1265,8 @@ class SaleOrder(models.Model):
UserError('Real Delivery Address harus di isi')
if order.validate_partner_invoice_due():
- return self._create_notification_action('Notification','Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
+ return self._create_notification_action('Notification',
+ 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
term_days = 0
for term_line in order.payment_term_id.line_ids:
@@ -1245,13 +1284,15 @@ class SaleOrder(models.Model):
if (partner.customer_type == 'pkp' or order.customer_type == 'pkp') and order.sppkp != partner.sppkp:
raise UserError("SPPKP berbeda pada Master Data Customer")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
- raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ raise UserError(
+ "Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
if not order.user_id.active:
raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact")
-
+
if order.validate_partner_invoice_due():
- return self._create_notification_action('Notification', 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
-
+ return self._create_notification_action('Notification',
+ 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
+
if order._requires_approval_margin_leader():
order.approval_status = 'pengajuan2'
return self._create_approval_notification('Pimpinan')
@@ -1261,9 +1302,9 @@ class SaleOrder(models.Model):
self.check_limit_so_to_invoice()
order.approval_status = 'pengajuan1'
return self._create_approval_notification('Sales Manager')
-
+
raise UserError("Bisa langsung Confirm")
-
+
def send_notif_to_salesperson(self, cancel=False):
if not cancel:
@@ -1281,7 +1322,9 @@ class SaleOrder(models.Model):
salesperson_data = {}
for rec in grouping_so:
if rec.user_id.id not in salesperson_data:
- salesperson_data[rec.user_id.id] = {'name': rec.user_id.name, 'orders': [], 'total_amount': 0, 'sum_total_amount': 0, 'business_partner': '', 'site': ''} # Menetapkan nilai awal untuk 'site'
+ salesperson_data[rec.user_id.id] = {'name': rec.user_id.name, 'orders': [], 'total_amount': 0,
+ 'sum_total_amount': 0, 'business_partner': '',
+ 'site': ''} # Menetapkan nilai awal untuk 'site'
if rec.picking_ids:
if not any(picking.state in ['assigned', 'confirmed', 'waiting'] for picking in rec.picking_ids):
continue
@@ -1300,7 +1343,8 @@ class SaleOrder(models.Model):
})
salesperson_data[rec.user_id.id]['sum_total_amount'] += order_total_amount
salesperson_data[rec.user_id.id]['business_partner'] = grouping_so[0].partner_id.main_parent_id.name
- salesperson_data[rec.user_id.id]['site'] = grouping_so[0].partner_id.site_id.name # Menambahkan nilai hanya jika ada
+ salesperson_data[rec.user_id.id]['site'] = grouping_so[
+ 0].partner_id.site_id.name # Menambahkan nilai hanya jika ada
# Kirim email untuk setiap salesperson
for salesperson_id, data in salesperson_data.items():
@@ -1324,9 +1368,9 @@ class SaleOrder(models.Model):
template = self.env.ref('indoteknik_custom.mail_template_sale_order_notification_to_salesperson')
email_body = template.body_html.replace('${table_content}', table_content)
email_body = email_body.replace('${salesperson_name}', data['name'])
- email_body = email_body.replace('${sum_total_amount}', str(data['sum_total_amount']))
- email_body = email_body.replace('${site}', str(data['site']))
- email_body = email_body.replace('${business_partner}', str(data['business_partner']))
+ email_body = email_body.replace('${sum_total_amount}', str(data['sum_total_amount']))
+ email_body = email_body.replace('${site}', str(data['site']))
+ email_body = email_body.replace('${business_partner}', str(data['business_partner']))
# Kirim email
self.env['mail.mail'].create({
'subject': 'Notification: Sale Orders',
@@ -1362,8 +1406,9 @@ class SaleOrder(models.Model):
if (outstanding_amount + rec.amount_total) >= block_stage:
if block_stage != 0:
remaining_credit_limit = block_stage - outstanding_amount
- raise UserError(_("%s is in Blocking Stage, Remaining credit limit is %s, from %s and outstanding %s")
- % (rec.partner_id.name, remaining_credit_limit, block_stage, outstanding_amount))
+ raise UserError(
+ _("%s is in Blocking Stage, Remaining credit limit is %s, from %s and outstanding %s")
+ % (rec.partner_id.name, remaining_credit_limit, block_stage, outstanding_amount))
def check_limit_so_to_invoice(self):
for rec in self:
@@ -1385,7 +1430,8 @@ class SaleOrder(models.Model):
# Validasi limit
if remaining_credit_limit <= 0 and block_stage > 0 and not is_cbd:
- raise UserError(_("The credit limit for %s will exceed the Blocking Stage if the Sale Order is confirmed. The remaining credit limit is %s, from %s and the outstanding amount is %s.")
+ raise UserError(
+ _("The credit limit for %s will exceed the Blocking Stage if the Sale Order is confirmed. The remaining credit limit is %s, from %s and the outstanding amount is %s.")
% (rec.partner_id.name, block_stage - current_total, block_stage, outstanding_amount))
def validate_different_vendor(self):
@@ -1395,11 +1441,11 @@ class SaleOrder(models.Model):
if self.vendor_approval_id and all(v.state != 'draft' for v in self.vendor_approval_id):
return False
-
+
different_vendor = self.order_line.filtered(
lambda l: l.vendor_id and l.vendor_md_id and l.vendor_id.id != l.vendor_md_id.id
)
-
+
if different_vendor:
vendor_approvals = []
for line in different_vendor:
@@ -1425,15 +1471,14 @@ class SaleOrder(models.Model):
if line.purchase_price_md else False
),
})
-
+
vendor_approvals.append(vendor_approval.id)
-
+
self.vendor_approval_id = [(4, vid) for vid in vendor_approvals]
return True
else:
return False
-
def action_confirm(self):
for order in self:
order._validate_uniform_taxes()
@@ -1443,38 +1488,41 @@ class SaleOrder(models.Model):
order.check_limit_so_to_invoice()
if self.validate_different_vendor() and not self.vendor_approval:
return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor')
-
+
order.check_data_real_delivery_address()
order.sale_order_check_approve()
order._validate_order()
order.order_line.validate_line()
-
+
main_parent = order.partner_id.get_main_parent()
SYSTEM_UID = 25
FROM_WEBSITE = order.create_uid.id == SYSTEM_UID
-
- if FROM_WEBSITE and main_parent.use_so_approval and order.web_approval not in ['cust_procurement', 'cust_director']:
+
+ if FROM_WEBSITE and main_parent.use_so_approval and order.web_approval not in ['cust_procurement',
+ 'cust_director']:
raise UserError("This order not yet approved by customer procurement or director")
if not order.client_order_ref and order.create_date > datetime(2024, 6, 27):
- raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
+ raise UserError(
+ "Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO")
if not order.commitment_date and order.create_date > datetime(2024, 9, 12):
raise UserError("Expected Delivery Date kosong, wajib diisi")
-
+
if not order.real_shipping_id:
UserError('Real Delivery Address harus di isi')
-
+
if order.validate_partner_invoice_due():
- return self._create_notification_action('Notification', 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
-
+ return self._create_notification_action('Notification',
+ 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
+
if order._requires_approval_margin_leader():
order.approval_status = 'pengajuan2'
return self._create_approval_notification('Pimpinan')
elif order._requires_approval_margin_manager():
order.approval_status = 'pengajuan1'
return self._create_approval_notification('Sales Manager')
-
+
order.approval_status = 'approved'
order._set_sppkp_npwp_contact()
order.calculate_line_no()
@@ -1488,7 +1536,7 @@ class SaleOrder(models.Model):
for line in order.order_line:
if line.display_type == 'line_note':
note.append(line.name)
-
+
if order.picking_ids:
# Sort picking_ids by creation date to get the most recent one
latest_picking = order.picking_ids.sorted(key=lambda p: p.create_date, reverse=True)[0]
@@ -1502,7 +1550,7 @@ class SaleOrder(models.Model):
main_parent = self.partner_id.get_main_parent()
if self._name != 'sale.order':
return super(SaleOrder, self).action_cancel()
-
+
if self.have_outstanding_invoice:
raise UserError("Invoice harus di Cancel dahulu")
@@ -1513,7 +1561,7 @@ class SaleOrder(models.Model):
for line in self.order_line:
if line.qty_delivered > 0:
raise UserError("DO yang done harus di-Return oleh Logistik")
-
+
if not self.web_approval:
self.web_approval = 'company'
# elif self.have_outstanding_po:
@@ -1543,11 +1591,11 @@ class SaleOrder(models.Model):
def validate_partner_invoice_due(self):
parent_id = self.partner_id.parent_id.id
- parent_id = parent_id if parent_id else self.partner_id.id
+ parent_id = parent_id if parent_id else self.partner_id.id
if self.due_id and self.due_id.is_approve == False:
raise UserError('Document Over Due Yang Anda Buat Belum Di Approve')
-
+
query = [
('partner_id', '=', parent_id),
('state', '=', 'posted'),
@@ -1570,27 +1618,27 @@ class SaleOrder(models.Model):
else:
due_extension.unlink()
return False
-
+
def _requires_approval_margin_leader(self):
return self.total_percent_margin <= 15 and not self.env.user.is_leader
-
+
def _requires_approval_margin_manager(self):
return 15 < self.total_percent_margin <= 24 and not self.env.user.is_sales_manager and not self.env.user.is_leader
# return self.total_percent_margin >= 15 and not self.env.user.is_leader and not self.env.user.is_sales_manager
-
+
def _create_approval_notification(self, approval_role):
title = 'Warning'
message = f'SO butuh approval {approval_role}'
return self._create_notification_action(title, message)
-
+
def _create_notification_action(self, title, message):
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
- 'params': { 'title': title, 'message': message, 'next': {'type': 'ir.actions.act_window_close'} },
+ 'params': {'title': title, 'message': message, 'next': {'type': 'ir.actions.act_window_close'}},
}
-
- def _set_sppkp_npwp_contact(self):
+
+ def _set_sppkp_npwp_contact(self):
partner = self.partner_id.parent_id or self.partner_id
if not partner.sppkp:
@@ -1609,7 +1657,7 @@ class SaleOrder(models.Model):
# 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)
@@ -1617,7 +1665,7 @@ class SaleOrder(models.Model):
total_margin -= order.ongkir_ke_xpdc
order.total_margin = total_margin
-
+
def _compute_total_before_margin(self):
for order in self:
total_before_margin = sum(line.item_before_margin for line in order.order_line if line.product_id)
@@ -1632,9 +1680,10 @@ class SaleOrder(models.Model):
delivery_amt = order.delivery_amt
else:
delivery_amt = 0
-
+
# order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2)
- order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-order.fee_third_party-order.biaya_lain_lain)) * 100, 2)
+ order.total_percent_margin = round(
+ (order.total_margin / (order.amount_untaxed - order.fee_third_party - order.biaya_lain_lain)) * 100, 2)
# order.total_percent_margin = round((order.total_margin / (order.amount_untaxed)) * 100, 2)
@api.onchange('sales_tax_id')
@@ -1657,20 +1706,20 @@ class SaleOrder(models.Model):
voucher = self.voucher_id
if voucher.limit > 0 and voucher.count_order >= voucher.limit:
raise UserError('Voucher tidak dapat digunakan karena sudah habis digunakan')
-
+
partner_voucher_orders = []
for order in voucher.order_ids:
if order.partner_id.id == self.partner_id.id:
partner_voucher_orders.append(order)
-
+
if voucher.limit_user > 0 and len(partner_voucher_orders) >= voucher.limit_user:
raise UserError('Voucher tidak dapat digunakan karena Customer ini sudah menghabiskan kuota voucher')
-
+
if self.pricelist_id.id in [x.id for x in voucher.excl_pricelist_ids]:
raise UserError('Voucher tidak dapat digunakan karena pricelist ini tidak berlaku pada voucher')
-
+
self.apply_voucher()
-
+
def action_apply_voucher_shipping(self):
for line in self.order_line:
if line.order_promotion_id:
@@ -1679,18 +1728,18 @@ class SaleOrder(models.Model):
voucher = self.voucher_shipping_id
if voucher.limit > 0 and voucher.count_order >= voucher.limit:
raise UserError('Voucher tidak dapat digunakan karena sudah habis digunakan')
-
+
partner_voucher_orders = []
for order in voucher.order_ids:
if order.partner_id.id == self.partner_id.id:
partner_voucher_orders.append(order)
-
+
if voucher.limit_user > 0 and len(partner_voucher_orders) >= voucher.limit_user:
raise UserError('Voucher tidak dapat digunakan karena Customer ini sudah menghabiskan kuota voucher')
-
+
if self.pricelist_id.id in [x.id for x in voucher.excl_pricelist_ids]:
raise UserError('Voucher tidak dapat digunakan karena pricelist ini tidak berlaku pada voucher')
-
+
self.apply_voucher_shipping()
def apply_voucher(self):
@@ -1707,7 +1756,7 @@ class SaleOrder(models.Model):
for line in self.order_line:
line.initial_discount = line.discount
-
+
voucher_type = voucher['type']
used_total = voucher['total'][voucher_type]
used_discount = voucher['discount'][voucher_type]
@@ -1723,11 +1772,11 @@ class SaleOrder(models.Model):
line_contribution = line.price_subtotal / used_total
line_voucher = used_discount * line_contribution
line_voucher_item = line_voucher / line.product_uom_qty
-
+
line_price_unit = line.price_unit / 1.11 if any(tax.id == 23 for tax in line.tax_id) else line.price_unit
line_discount_item = line_price_unit * line.discount / 100 + line_voucher_item
line_voucher_item = line_discount_item / line_price_unit * 100
-
+
line.amount_voucher_disc = line_voucher
line.discount = line_voucher_item
@@ -1738,27 +1787,27 @@ class SaleOrder(models.Model):
for order in self:
delivery_amt = order.delivery_amt
voucher = order.voucher_shipping_id
-
+
if voucher:
max_discount_amount = voucher.discount_amount
voucher_type = voucher.discount_type
-
+
if voucher_type == 'fixed_price':
discount = max_discount_amount
elif voucher_type == 'percentage':
discount = delivery_amt * (max_discount_amount / 100)
-
+
delivery_amt -= discount
-
+
delivery_amt = max(delivery_amt, 0)
-
+
order.delivery_amt = delivery_amt
-
+
order.amount_voucher_shipping_disc = discount
order.applied_voucher_shipping_id = order.voucher_id.id
def cancel_voucher(self):
- self.applied_voucher_id = False
+ self.applied_voucher_id = False
self.amount_voucher_disc = 0
for line in self.order_line:
line.amount_voucher_disc = 0
@@ -1767,17 +1816,18 @@ class SaleOrder(models.Model):
def cancel_voucher_shipping(self):
self.delivery_amt + self.amount_voucher_shipping_disc
- self.applied_voucher_shipping_id = False
+ self.applied_voucher_shipping_id = False
self.amount_voucher_shipping_disc = 0
def action_web_approve(self):
if self.env.uid != self.partner_id.user_id.id:
- raise UserError('You are not authorized to approve this order. Only %s can approve this order.' % self.partner_id.user_id.name)
-
+ raise UserError(
+ 'You are not authorized to approve this order. Only %s can approve this order.' % self.partner_id.user_id.name)
+
self.web_approval = 'company'
template = self.env.ref('indoteknik_custom.mail_template_sale_order_web_approve_notification')
template.send_mail(self.id, force_send=True)
-
+
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
@@ -1837,13 +1887,14 @@ class SaleOrder(models.Model):
if last_so and rec_purchase_price != last_so.purchase_price:
rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1)
if rec_taxes.price_include:
- selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100))
+ selling_price = (rec_purchase_price / 1.11) / (
+ 1 - (last_so.item_percent_margin_without_deduction / 100))
else:
selling_price = rec_purchase_price / (1 - (last_so.item_percent_margin_without_deduction / 100))
tax_id = last_so.tax_id
for tax in tax_id:
if tax.price_include:
- selling_price = selling_price + (selling_price*11/100)
+ selling_price = selling_price + (selling_price * 11 / 100)
else:
selling_price = selling_price
discount = 0
@@ -1859,13 +1910,14 @@ class SaleOrder(models.Model):
elif last_so and rec_vendor_id == order_line.vendor_id.id and rec_purchase_price != last_so.purchase_price:
rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1)
if rec_taxes.price_include:
- selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100))
+ selling_price = (rec_purchase_price / 1.11) / (
+ 1 - (last_so.item_percent_margin_without_deduction / 100))
else:
selling_price = rec_purchase_price / (1 - (last_so.item_percent_margin_without_deduction / 100))
tax_id = last_so.tax_id
for tax in tax_id:
if tax.price_include:
- selling_price = selling_price + (selling_price*11/100)
+ selling_price = selling_price + (selling_price * 11 / 100)
else:
selling_price = selling_price
discount = 0
@@ -1896,14 +1948,14 @@ class SaleOrder(models.Model):
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()
+ # 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
+ # return res
def _update_partner_details(self):
for order in self:
@@ -1932,11 +1984,11 @@ class SaleOrder(models.Model):
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 \ No newline at end of file
+ self._calculate_etrts_date()
+ return res