From 095e0a6815bcc64d638d64f72f5f392aa92ec7b6 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 31 May 2023 11:10:48 +0700 Subject: bug fix sale monitoring detail --- indoteknik_custom/models/sale_monitoring_detail.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py index a578f67b..6c609ac2 100755 --- a/indoteknik_custom/models/sale_monitoring_detail.py +++ b/indoteknik_custom/models/sale_monitoring_detail.py @@ -60,7 +60,7 @@ class SaleMonitoringDetail(models.Model): WHERE pt.type IN ('consu','product') AND so.state IN ('sale','done') AND so.create_date >= '2022-08-10' - and so.so_status not in('terproses') + and (so.so_status not in('terproses') or so.invoice_status not in('invoiced')) ) a ) """ % self._table) -- cgit v1.2.3 From 21f7c7a9b5ad175994b0824f82f9459feed3ca90 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 31 May 2023 14:09:59 +0700 Subject: add calculate all so status function --- indoteknik_custom/models/sale_monitoring_detail.py | 2 +- indoteknik_custom/models/sale_order.py | 27 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py index 6c609ac2..a578f67b 100755 --- a/indoteknik_custom/models/sale_monitoring_detail.py +++ b/indoteknik_custom/models/sale_monitoring_detail.py @@ -60,7 +60,7 @@ class SaleMonitoringDetail(models.Model): WHERE pt.type IN ('consu','product') AND so.state IN ('sale','done') AND so.create_date >= '2022-08-10' - and (so.so_status not in('terproses') or so.invoice_status not in('invoiced')) + and so.so_status not in('terproses') ) a ) """ % self._table) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 85d7e595..d7b4331a 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -116,6 +116,33 @@ class SaleOrder(models.Model): sale.so_status = 'terproses' _logger.info('Calculate SO Status %s' % sale.id) + def _calculate_all_so_status(self, limit=500): + so_state = ['sale'] + sales = self.env['sale.order'].search([ + ('state', 'in', so_state), + # ('so_status', '!=', 'terproses'), + ], order='id desc', limit=limit) + for sale in sales: + sum_qty_ship = sum_qty_so = 0 + have_outstanding_pick = False + + for pick in sale.picking_ids: + if pick.state == 'draft' or pick.state == 'assigned' or pick.state == 'confirmed' or pick.state == 'waiting': + have_outstanding_pick = True + + for so_line in sale.order_line: + sum_qty_so += so_line.product_uom_qty + sum_qty_ship += so_line.qty_delivered + + if have_outstanding_pick: + if sum_qty_so > sum_qty_ship > 0: + sale.so_status = 'sebagian' + else: + sale.so_status = 'menunggu' + else: + sale.so_status = 'terproses' + _logger.info('Calculate All SO Status %s' % sale.id) + def calculate_so_status(self): so_state = ['sale'] sales = self.env['sale.order'].search([ -- cgit v1.2.3 From caae31d0376d62ca62a6d4e3fa5aaa0842fc9c88 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 31 May 2023 15:36:00 +0700 Subject: new module of requisition --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/automatic_purchase.py | 2 +- indoteknik_custom/models/requisition.py | 179 +++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/requisition.py (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 18f46d34..9764e0c0 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -62,3 +62,4 @@ from . import raja_ongkir from . import procurement_monitoring_detail from . import brand_vendor from . import manufacturing +from . import requisition diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index eea66b99..87319bf6 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -88,7 +88,7 @@ class AutomaticPurchase(models.Model): if point.product_id.virtual_available > point.product_min_qty: continue qty_purchase = point.product_max_qty - point.product_id.virtual_available - po_line = self.env['purchase.order.line'].search([('product_id', '=', point.product_id.id), ('order_id.state', '=', 'done')], limit=1) + po_line = self.env['purchase.order.line'].search([('product_id', '=', point.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1) if self.vendor_id: purchase_price = self.env['purchase.pricelist'].search([ diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py new file mode 100644 index 00000000..01d5ef55 --- /dev/null +++ b/indoteknik_custom/models/requisition.py @@ -0,0 +1,179 @@ +from odoo import models, fields, api +from odoo.exceptions import UserError +from datetime import datetime +import logging + +_logger = logging.getLogger(__name__) + + +class Requisition(models.Model): + _name = 'requisition' + _order = 'id desc' + + number = fields.Char(string='Document No', index=True, copy=False, readonly=True) + date_doc = fields.Date(string='Date', help='isi tanggal hari ini') + description = fields.Char(string='Description', help='bebas isinya apa aja') + requisition_lines = fields.One2many('requisition.line', 'requisition_id', string='Lines', auto_join=True) + notification = fields.Char(string='Notification') + is_po = fields.Boolean(string='Is PO') + requisition_match = fields.One2many('requisition.purchase.match', 'requisition_id', string='Matches', auto_join=True) + sale_order_id = fields.Many2one('sale.order', string='SO', help='harus diisi nomor SO yang ingin digenerate', + domain="[('state', '=', 'sale')]") + + @api.model + def create(self, vals): + vals['number'] = self.env['ir.sequence'].next_by_code('requisition') or '0' + result = super(Requisition, self).create(vals) + return result + + def create_requisition_from_sales(self): + if self.requisition_lines: + raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu') + if not self.sale_order_id: + raise UserError('Sale Order harus diisi') + if self.is_po: + raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya') + + old_requisition = self.env['requisition'].search([('sale_order_id', '=', self.sale_order_id.id)], limit=1) + if old_requisition: + raise UserError('Sudah pernah jadi Requisition') + + count = 0 + for order_line in self.sale_order_id.order_line: + # get purchase price altama, if nothing, then get other cheaper, if nothing then last po + purchase_price = 0 + vendor_id = 0 + + purchase_pricelist = self.env['purchase.pricelist'].search([ + ('product_id.id', '=', order_line.product_id.id), + ('vendor_id.id', '=', 5571) + ], order='product_price asc', limit=1) + purchase_price = purchase_pricelist.product_price + vendor_id = purchase_pricelist.vendor_id.id + source = 'PriceList' + + if not purchase_price or purchase_price <= 0: + purchase_pricelist = self.env['purchase.pricelist'].search([('product_id', '=', order_line.product_id.id)], order='product_price asc', limit=1) + purchase_price = purchase_pricelist.product_price + vendor_id = purchase_pricelist.vendor_id.id + source = 'PriceList' + + if not purchase_price or purchase_price <= 0: + last_po_line = self.env['purchase.order.line'].search([('product_id', '=', order_line.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1) + purchase_price = last_po_line.price_unit + vendor_id = last_po_line.order_id.partner_id.id + source = 'LastPO' + + if not purchase_price or purchase_price <= 0: + purchase_price = 0 + vendor_id = 5571 + source = 'Nothing' + + self.env['requisition.line'].create([{ + 'requisition_id': self.id, + 'partner_id': vendor_id, + 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id, + 'product_id': order_line.product_id.id, + 'qty_purchase': order_line.product_uom_qty, + 'tax_id': order_line.purchase_tax_id.id, + 'price_unit': purchase_price, + 'subtotal': purchase_price * order_line.product_uom_qty, + 'source': source + }]) + count+=1 + _logger.info('Create Requisition %s' % order_line.product_id.name) + self.notification = "Requisition Created %s lines" % count + + def create_po_from_requisition(self): + if not self.requisition_lines: + raise UserError('Tidak ada Lines, belum bisa create PO') + if self.is_po: + raise UserError('Sudah pernah di create PO') + current_time = datetime.now() + vendor_ids = self.env['requisition.line'].read_group([('requisition_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id']) + + counter_po_number = 0 + for vendor in vendor_ids: + param_header = { + 'partner_id': vendor['partner_id'][0], + 'partner_ref': self.sale_order_id.name, + 'currency_id': 12, + 'user_id': self.env.user.id, + 'company_id': 1, # indoteknik dotcom gemilang + 'picking_type_id': 28, # indoteknik bandengan receipts + 'date_order': current_time, + 'sale_order_id': self.sale_order_id.id + } + # new_po = self.env['purchase.order'].create([param_header]) + products_vendors = self.env['requisition.line'].search([ + ('requisition_id', '=', self.id), + ('partner_id', '=', vendor['partner_id'][0]), + ('qty_purchase', '>', 0) + ], order='brand_id') + count = brand_id = 0 + new_po = '' + for product in products_vendors: + if not new_po or ((count == 200 or brand_id != product.brand_id.id) and vendor['partner_id'][0] == 5571): + count = 0 + counter_po_number += 1 + new_po = self.env['purchase.order'].create([param_header]) + new_po.name = new_po.name + "/R/"+str(counter_po_number) + self.env['requisition.purchase.match'].create([{ + 'requisition_id': self.id, + 'order_id': new_po.id + }]) + self.env.cr.commit() + # else: + # new_po = self.env['purchase.order'].create([param_header]) + brand_id = product.brand_id.id + count += 10 + param_line = { + 'order_id': new_po.id, + 'sequence': count, + 'product_id': product.product_id.id, + 'product_qty': product.qty_purchase, + 'product_uom_qty': product.qty_purchase, + 'price_unit': product.last_price, + 'taxes_id': product.tax_id + } + new_line = self.env['purchase.order.line'].create([param_line]) + product.current_po_id = new_po.id + product.current_po_line_id = new_line.id + _logger.info('Create PO Line %s' % product.product_id.name) + self.notification = self.notification + ' %s' % new_po.name + self.is_po = True + +class RequisitionLine(models.Model): + _name = 'requisition.line' + _description = 'Requisition Line' + _order = 'requisition_id, id' + + requisition_id = fields.Many2one('requisition', string='Ref', required=True, ondelete='cascade', index=True, copy=False) + brand_id = fields.Many2one('x_manufactures', string='Brand') + product_id = fields.Many2one('product.product', string='Product') + partner_id = fields.Many2one('res.partner', string='Vendor') + qty_purchase = fields.Float(string='Qty Purchase') + price_unit = fields.Float(string='Price') + tax_id = fields.Many2one('account.tax', help='isi tax pembelian include atau exclude', domain="[('type_tax_use', '=', 'purchase')]") + subtotal = fields.Float(string='Subtotal') + last_price = fields.Float(string='Last Price') + last_order_id = fields.Many2one('purchase.order', string='Last Order') + last_orderline_id = fields.Many2one('purchase.order.line', string='Last Order Line') + is_po = fields.Boolean(String='Is PO') + current_po_id = fields.Many2one('purchase.order', string='Current') + current_po_line_id = fields.Many2one('purchase.order.line', string='Current Line') + source = fields.Char(string='Source', help='data harga diambil darimana') + +class RequisitionPurchaseMatch(models.Model): + _name = 'requisition.purchase.match' + _order = 'requisition_id, id' + + requisition_id = fields.Many2one('requisition', string='Ref', required=True, ondelete='cascade', index=True, copy=False) + order_id = fields.Many2one('purchase.order', string='Purchase Order') + vendor = fields.Char(string='Vendor', compute='_compute_info_po') + total = fields.Float(string='Total', compute='_compute_info_po') + + def _compute_info_po(self): + for match in self: + match.vendor = match.order_id.partner_id.name + match.total = match.order_id.amount_total -- cgit v1.2.3 From 673e5500269f96492a447eb7ea38ed16b1827468 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 2 Jun 2023 10:23:05 +0700 Subject: ceiling price exclude after discount --- indoteknik_custom/models/apache_solr.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/apache_solr.py b/indoteknik_custom/models/apache_solr.py index a988a8d3..9f187d78 100644 --- a/indoteknik_custom/models/apache_solr.py +++ b/indoteknik_custom/models/apache_solr.py @@ -168,3 +168,12 @@ class ApacheSolr(models.Model): _solr.add(documents) end_time = time.time() _logger.info("[SYNC_PRODUCT_TO_SOLR] Finish task add to solr. Time taken: {:.6f} seconds".format(end_time - start_time)) + + def _test_product_price(self, product_id=228178): + product = self.env['product.product'].search([('id', '=', product_id)], limit=1) + _logger.info('price incl tax: %s' % product._get_website_price_include_tax()) + _logger.info('price excl tax: %s' % product._get_website_price_exclude_tax()) + _logger.info('discount : %s' % product._get_website_disc(0)) + _logger.info('price after discount : %s' % product._get_website_price_after_disc()) + _logger.info('price excl after discount : %s' % product._get_website_price_after_disc_and_tax()) + _logger.info('tax : %s' % product._get_website_tax()) -- cgit v1.2.3 From aff9fdd49543648bfed395fff0c86af5b0269686 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 2 Jun 2023 14:16:33 +0700 Subject: add feature generate payment link midtrans --- indoteknik_custom/models/sale_order.py | 33 +++++++++++++++++++++++++++++++ indoteknik_custom/models/stock_picking.py | 5 +++++ 2 files changed, 38 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d7b4331a..d021934f 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -5,6 +5,9 @@ import logging import warnings import random import string +import requests +import math +import json _logger = logging.getLogger(__name__) @@ -74,6 +77,36 @@ class SaleOrder(models.Model): 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') + + 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 + so_number = self.name + so_number = so_number.replace('/', '-') + so_grandtotal = math.floor(self.grand_total) + headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'Authorization': midtrans_auth, + } + + json_data = { + 'transaction_details': { + 'order_id': so_number, + 'gross_amount': so_grandtotal, + }, + 'credit_card': { + 'secure': True, + }, + } + + response = requests.post(midtrans_url, headers=headers, json=json_data).json() + lookup_json = json.dumps(response, indent=4, sort_keys=True) + redirect_url = json.loads(lookup_json)['redirect_url'] + self.payment_link_midtrans = str(redirect_url) @api.model def _generate_so_access_token(self, limit=50): diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index e63370f5..8c366082 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -256,6 +256,11 @@ class StockPicking(models.Model): if self.is_internal_use and not self.env.user.is_accounting: raise UserError("Harus di Approve oleh Accounting") + + if self.group_id.sale_id: + if self.group_id.sale_id.payment_link_midtrans: + if self.group_id.sale_id.payment_status != 'settlement': + raise UserError('Uang belum masuk (settlement), mohon konfirmasi ke sales atau finance') if self.is_internal_use: stock_move_lines = self.env['stock.move.line'].search([ -- cgit v1.2.3 From ed2cd466938f7aee19688b6402edbb3643ee21e1 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Fri, 2 Jun 2023 15:41:53 +0700 Subject: add missing table validation before run validate --- indoteknik_custom/models/stock_picking.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 8c366082..54b478ae 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -248,6 +248,9 @@ class StockPicking(models.Model): return def button_validate(self): + if self._name != 'stock.picking': + return super(StockPicking, self).button_validate() + if not self.picking_code: self.picking_code = self.env['ir.sequence'].next_by_code('stock.picking.code') or '0' -- cgit v1.2.3 From 7ffcb706cfbacdc7abf11c239073acadaae469a7 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 5 Jun 2023 09:43:28 +0700 Subject: fix compute grand total in sales order --- indoteknik_custom/models/sale_order.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d021934f..735a467c 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -425,7 +425,10 @@ class SaleOrder(models.Model): def _compute_grand_total(self): for order in self: - order.grand_total = order.delivery_amt + order.amount_total + if order.shipping_cost_covered == 'customer': + order.grand_total = order.delivery_amt + order.amount_total + else: + order.grand_total = order.amount_total class SaleOrderLine(models.Model): -- cgit v1.2.3 From 25ad8547cc4aab608478d52352d834579f26c88d Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 5 Jun 2023 11:00:42 +0700 Subject: add validation qty invoice cant greater than qty order in invoice customer and vendor --- indoteknik_custom/models/account_move.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 56f3e82c..c2e93632 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -33,13 +33,36 @@ class AccountMove(models.Model): return res def action_post(self): + if self._name != 'account.move': + return super(AccountMove, self).action_post() + + # validation cant qty invoice greater than qty order + if self.move_type == 'out_invoice': + query = ["&",("name","=",self.invoice_origin),"|",("state","=","sale"),("state","=","done")] + sale_order = self.env['sale.order'].search(query, limit=1) + sum_qty_invoice = sum_qty_order = 0 + for line in sale_order.order_line: + sum_qty_invoice += line.qty_invoiced + sum_qty_order += line.product_uom_qty + if sum_qty_invoice > sum_qty_order: + raise UserError('Error Qty Invoice akan lebih besar dari Qty Order jika lanjut Posting') + elif self.move_type == 'in_invoice': + query = ["&",("name","=",self.invoice_origin),"|",("state","=","purchase"),("state","=","done")] + purchase_order = self.env['purchase.order'].search(query, limit=1) + sum_qty_invoice = sum_qty_order = 0 + for line in purchase_order.order_line: + sum_qty_invoice += line.qty_invoiced + sum_qty_order += line.product_uom_qty + if sum_qty_invoice > sum_qty_order: + raise UserError('Error Qty Invoice akan lebih besar dari Qty Order jika lanjut Posting') + res = super(AccountMove, self).action_post() # if not self.env.user.is_accounting: # raise UserError('Hanya Accounting yang bisa Posting') - if self._name == 'account.move': - for entry in self: - for line in entry.line_ids: - line.date_maturity = entry.date + # if self._name == 'account.move': + for entry in self: + for line in entry.line_ids: + line.date_maturity = entry.date return res def _compute_invoice_day_to_due(self): -- cgit v1.2.3 From 48474fcef12509f736be0cb6af47618601dbfe61 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 7 Jun 2023 10:29:19 +0700 Subject: remove useless validation in manufacturing order and custom landed cost --- indoteknik_custom/models/manufacturing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/manufacturing.py b/indoteknik_custom/models/manufacturing.py index 15756e44..2455a117 100644 --- a/indoteknik_custom/models/manufacturing.py +++ b/indoteknik_custom/models/manufacturing.py @@ -25,8 +25,8 @@ class Manufacturing(models.Model): return super(Manufacturing, self).button_mark_done() 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.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') -- cgit v1.2.3 From 242bac3811359cdf80954fd3ef82a04a2537410b Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 7 Jun 2023 11:41:11 +0700 Subject: add validation can sell product in sale order --- indoteknik_custom/models/sale_order.py | 37 +++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 735a467c..1bdc7f7d 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -228,7 +228,7 @@ class SaleOrder(models.Model): order.have_outstanding_invoice = False def _have_outstanding_picking(self): - picking_state = ['done', 'confirmed', 'draft', 'cancel'] + picking_state = ['done', 'confirmed', 'draft'] for order in self: if not order.picking_ids: order.have_outstanding_picking = False @@ -309,6 +309,9 @@ class SaleOrder(models.Model): if not order.carrier_id: raise UserError("Shipping Method harus diisi") for line in order.order_line: + # must add product can sell validation + if not line.product_id.product_tmpl_id.sale_ok: + raise UserError('Product ini belum bisa dijual, harap hubungi finance') if not line.product_id or line.product_id.type == 'service': continue if line.product_id.id == 232383: @@ -326,12 +329,15 @@ class SaleOrder(models.Model): def action_cancel(self): # TODO stephan prevent cancel if have invoice, do, and po + if self._name != 'sale.order': + return super(SaleOrder, self).action_cancel() + if self.have_outstanding_invoice: raise UserError("Invoice harus di Cancel dahulu") - # elif self.have_outstanding_picking: - # raise UserError("DO harus di Cancel dahulu") - # elif self.have_outstanding_po: - # raise UserError("PO harus di Cancel dahulu") + elif self.have_outstanding_picking: + raise UserError("DO harus di Cancel dahulu") + elif self.have_outstanding_po: + raise UserError("PO harus di Cancel dahulu") self.approval_status = False return super(SaleOrder, self).action_cancel() @@ -347,6 +353,9 @@ class SaleOrder(models.Model): raise UserError("Shipping Method harus diisi") # approval1 = approval2 = 0 for line in order.order_line: + # must add product can sell validation + if not line.product_id.product_tmpl_id.sale_ok: + raise UserError('Product ini belum bisa dijual, harap hubungi finance') if not line.product_id or line.product_id.type == 'service': continue if line.product_id.id == 232383: @@ -485,15 +494,15 @@ class SaleOrderLine(models.Model): if not self.product_id or self.product_id.type == 'service': return elif self.product_id.categ_id.id == 34: # finish good / manufacturing only - print('a') - bom = self.env['mrp.bom'].search( - [('product_tmpl_id', '=', self.product_id.product_tmpl_id.id)] - , limit=1) - cost = 0 - for line in bom.bom_line_ids: - purchase_price = self.env['purchase.pricelist'].search( - [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', line.product_id.id)], limit=1) - cost += purchase_price.product_price + # bom = self.env['mrp.bom'].search( + # [('product_tmpl_id', '=', self.product_id.product_tmpl_id.id)] + # , limit=1) + # cost = 0 + # for line in bom.bom_line_ids: + # purchase_price = self.env['purchase.pricelist'].search( + # [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', line.product_id.id)], limit=1) + # cost += purchase_price.product_price + cost = self.product_id.standard_price self.purchase_price = cost else: purchase_price = self.env['purchase.pricelist'].search( -- cgit v1.2.3 From dd785718ca1e7fd1da034dec2bb2c8bf8381def6 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 7 Jun 2023 13:22:25 +0700 Subject: add missing validation while tag crm leads --- indoteknik_custom/models/crm_lead.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py index e7af4b1c..b87315ff 100755 --- a/indoteknik_custom/models/crm_lead.py +++ b/indoteknik_custom/models/crm_lead.py @@ -81,7 +81,7 @@ class CrmLead(models.Model): if not lead.partner_id: continue - if not lead.user_id or lead.user_id.id == 2: + if not lead.user_id or lead.user_id.id == 2 or lead.user_id.id == 25: if lead.partner_id.parent_id.user_id: salesperson_id = lead.partner_id.parent_id.user_id.id elif lead.partner_id.user_id: -- cgit v1.2.3 From a5e3151dc5afa25d9dc36d7448165eaa6654d4f9 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 9 Jun 2023 12:59:26 +0700 Subject: Disable button delete on table product and contact --- indoteknik_custom/models/product_template.py | 11 +++++++++++ indoteknik_custom/models/res_partner.py | 7 +++++++ 2 files changed, 18 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 49235ec7..9c480f4c 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -1,5 +1,6 @@ from odoo import fields, models, api from datetime import datetime, timedelta +from odoo.exceptions import AccessError, UserError, ValidationError import logging _logger = logging.getLogger(__name__) @@ -69,6 +70,10 @@ class ProductTemplate(models.Model): rate += 2 product.virtual_rating = rate + def unlink(self): + if self._name == 'product.template': + raise UserError('Maaf anda tidak bisa delete product') + def update_new_product(self): current_time = datetime.now() delta_time = current_time - timedelta(days=30) @@ -185,6 +190,8 @@ class ProductTemplate(models.Model): product.product_rating = rate product.last_calculate_rating = current_time + + class ProductProduct(models.Model): _inherit = "product.product" @@ -223,3 +230,7 @@ class ProductProduct(models.Model): for product in self: stock_vendor = self.env['stock.vendor'].search([('product_variant_id', '=', product.id)], limit=1) product.qty_stock_vendor = stock_vendor.quantity + product.qty_available + + def unlink(self): + if self._name == 'product.product': + raise UserError('Maaf anda tidak bisa delete product') \ No newline at end of file diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index eaf93717..77abaaf9 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -1,4 +1,5 @@ from odoo import models, fields +from odoo.exceptions import UserError, ValidationError class GroupPartner(models.Model): _name = 'group.partner' @@ -13,3 +14,9 @@ class ResPartner(models.Model): custom_pricelist_id = fields.Many2one('product.pricelist', string='Price Matrix') group_partner_id = fields.Many2one('group.partner', string='Group Partner') + def unlink(self): + if self._name == 'res.partner': + raise UserError('Maaf anda tidak bisa delete contact') + + + -- cgit v1.2.3 From b0effc107cd0dcb1d9f5a458a00b2c1170edf1e8 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 13 Jun 2023 13:38:21 +0700 Subject: Menambahkan detail validasi approve/confirm so jika barang tidak dijual --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 1bdc7f7d..e592326d 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -311,7 +311,7 @@ class SaleOrder(models.Model): for line in order.order_line: # must add product can sell validation if not line.product_id.product_tmpl_id.sale_ok: - raise UserError('Product ini belum bisa dijual, harap hubungi finance') + raise UserError('Product %s belum bisa dijual, harap hubungi finance' % line.product_id.display_name) if not line.product_id or line.product_id.type == 'service': continue if line.product_id.id == 232383: @@ -355,7 +355,7 @@ class SaleOrder(models.Model): for line in order.order_line: # must add product can sell validation if not line.product_id.product_tmpl_id.sale_ok: - raise UserError('Product ini belum bisa dijual, harap hubungi finance') + raise UserError('Product %s belum bisa dijual, harap hubungi finance' % line.product_id.display_name) if not line.product_id or line.product_id.type == 'service': continue if line.product_id.id == 232383: -- cgit v1.2.3 From 1cca590f07fd84a33626e5fc965924c617d8e287 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 13 Jun 2023 13:46:23 +0700 Subject: Bug fix error input note on sale order line validation --- indoteknik_custom/models/sale_order.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index e592326d..cefba3da 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -309,11 +309,11 @@ class SaleOrder(models.Model): if not order.carrier_id: raise UserError("Shipping Method harus diisi") for line in order.order_line: + if not line.product_id or line.product_id.type == 'service': + continue # must add product can sell validation if not line.product_id.product_tmpl_id.sale_ok: raise UserError('Product %s belum bisa dijual, harap hubungi finance' % line.product_id.display_name) - if not line.product_id or line.product_id.type == 'service': - continue if line.product_id.id == 232383: raise UserError(_('Tidak bisa Confirm menggunakan Produk Sementara')) if not line.vendor_id or not line.purchase_price: @@ -353,11 +353,11 @@ class SaleOrder(models.Model): raise UserError("Shipping Method harus diisi") # approval1 = approval2 = 0 for line in order.order_line: + if not line.product_id or line.product_id.type == 'service': + continue # must add product can sell validation if not line.product_id.product_tmpl_id.sale_ok: raise UserError('Product %s belum bisa dijual, harap hubungi finance' % line.product_id.display_name) - if not line.product_id or line.product_id.type == 'service': - continue if line.product_id.id == 232383: raise UserError(_('Tidak bisa Confirm menggunakan Produk Sementara')) if not line.vendor_id or not line.purchase_price or not line.purchase_tax_id: -- cgit v1.2.3 From 9f0f7d02b357b3bacc1d5d28855a23f3a544d543 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 14 Jun 2023 10:16:20 +0700 Subject: remove requisition validation --- indoteknik_custom/models/requisition.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 01d5ef55..5bb3272e 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -34,9 +34,9 @@ class Requisition(models.Model): if self.is_po: raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya') - old_requisition = self.env['requisition'].search([('sale_order_id', '=', self.sale_order_id.id)], limit=1) - if old_requisition: - raise UserError('Sudah pernah jadi Requisition') + # old_requisition = self.env['requisition'].search([('sale_order_id', '=', self.sale_order_id.id)], limit=1) + # if old_requisition: + # raise UserError('Sudah pernah jadi Requisition') count = 0 for order_line in self.sale_order_id.order_line: -- cgit v1.2.3 From 237ea1205935d9f1bea5eb704df02e3835f9f82a Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 14 Jun 2023 10:49:33 +0700 Subject: add note logistic for exclude calculate leadtime --- indoteknik_custom/models/stock_picking.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 54b478ae..c8424121 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -59,6 +59,10 @@ class StockPicking(models.Model): ('approved', 'Approved'), ], string='Approval Return Status', readonly=True, copy=False, index=True, tracking=3, help="Approval Status untuk Return") date_doc_kirim = fields.Datetime(string='Tanggal Kirim di SJ', help="Tanggal Kirim di cetakan SJ, tidak berpengaruh ke Accounting") + note_logistic = fields.Selection([ + ('hold', 'Hold by Sales'), + ('not_paid', 'Customer belum bayar') + ], string='Note', help='jika field ini diisi maka tidak akan dihitung ke lead time') def action_create_invoice_from_mr(self): """Create the invoice associated to the PO. -- cgit v1.2.3 From f6b57e41f73c0a64e64397223bbba17aa45de0f1 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 15 Jun 2023 08:53:42 +0700 Subject: make so_status didnt copy while duplicate sales order --- indoteknik_custom/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index cefba3da..cbc6a60a 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -53,7 +53,7 @@ class SaleOrder(models.Model): ('terproses', 'Terproses'), ('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.") -- cgit v1.2.3 From b1cad2a414cbb1d749bb2c0a23fab665519dfafd Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 15 Jun 2023 09:28:59 +0700 Subject: Change Request "Qty Available dibaca dari BU / Stock saja" --- indoteknik_custom/models/purchase_order.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index ea99e165..ea75539a 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -151,7 +151,10 @@ class PurchaseOrder(models.Model): self.order_line.unlink() for order_line in self.sale_order_id.order_line: if order_line.product_id.id and order_line.product_id.id not in products_exception: - qty_available = order_line.product_id.virtual_available + qty_available = self.env['stock.quant'].search([ + ('product_id', '=', order_line.product_id.id), + ('location_id', '=', "BU/Stock") + ], limit=1) suggest = 'harus beli' if order_line.product_id.virtual_available > order_line.product_qty: suggest = 'masih cukup' @@ -160,10 +163,10 @@ class PurchaseOrder(models.Model): 'product_id': order_line.product_id.id, 'name': order_line.product_id.display_name, 'product_qty': order_line.product_qty, - 'qty_available_store': qty_available, + 'qty_available_store': qty_available.available_quantity, 'suggest': suggest, } - self.env['purchase.order.line'].sudo().create(values) + self.order_line.create(values) def compute_count_line_product(self): for order in self: -- cgit v1.2.3 From 1edd55b85c24b8f9a36349fa34793cb65a554851 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 15 Jun 2023 11:50:08 +0700 Subject: add qty reserved in sale monitoring and sale monitoring detail --- indoteknik_custom/models/sale_monitoring.py | 9 +++++++-- indoteknik_custom/models/sale_monitoring_detail.py | 10 +++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_monitoring.py b/indoteknik_custom/models/sale_monitoring.py index a3265a8b..ea1e490c 100755 --- a/indoteknik_custom/models/sale_monitoring.py +++ b/indoteknik_custom/models/sale_monitoring.py @@ -20,6 +20,7 @@ class SaleMonitoring(models.Model): date_order = fields.Datetime(string="Date Order") status = fields.Char(string="Status") po_number = fields.Char(string="PO Number") + qty_reserved = fields.Integer(string="Qty Reserved") def init(self): tools.drop_view_if_exists(self.env.cr, self._table) @@ -36,9 +37,13 @@ class SaleMonitoring(models.Model): SUM(smd.qty_po_received) AS qty_po_received, SUM(smd.qty_so_delivered) AS qty_so_delivered, SUM(smd.qty_so_invoiced) AS qty_so_invoiced, + sum(smd.qty_reserved) as qty_reserved, CASE - WHEN SUM(qty_po) < SUM(qty_so) AND SUM(qty_po) <= 0 THEN 'Belum PO sama sekali' - WHEN SUM(qty_po) < SUM(qty_so) THEN 'Belum PO full' + WHEN SUM(qty_so) = SUM(qty_reserved) then 'SIAP KIRIM' + WHEN SUM(qty_so) = SUM(qty_so_delivered) then 'Delivered' + WHEN SUM(qty_so) = SUM(qty_so_invoiced) then 'Done' + WHEN SUM(qty_reserved) < SUM(qty_so) and SUM(qty_reserved) > 0 THEN 'Belum PO full' + WHEN SUM(qty_reserved) = SUM(qty_so) THEN 'Belum PO sama sekali' WHEN SUM(qty_po_received) < SUM(qty_so) AND SUM(qty_po_received) <= 0 THEN 'Belum Received sama sekali' WHEN SUM(qty_po_received) < SUM(qty_so) THEN 'Belum Received full' WHEN SUM(qty_to_delivered) = SUM(qty_so) THEN 'SIAP KIRIM' diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py index a578f67b..908ccb68 100755 --- a/indoteknik_custom/models/sale_monitoring_detail.py +++ b/indoteknik_custom/models/sale_monitoring_detail.py @@ -21,6 +21,7 @@ class SaleMonitoringDetail(models.Model): qty_so_invoiced = fields.Integer(string="Qty SO Invoiced") date_order = fields.Datetime(string="Date Order") status = fields.Char(string="Status") + qty_reserved = fields.Integer(string="Qty Reserved") def init(self): tools.drop_view_if_exists(self.env.cr, self._table) @@ -29,9 +30,11 @@ class SaleMonitoringDetail(models.Model): SELECT *, CASE + WHEN qty_so = qty_reserved then 'SIAP KIRIM' + WHEN qty_so = qty_so_delivered then 'Delivered' WHEN qty_so = qty_so_invoiced then 'Done' - WHEN qty_po < qty_so AND qty_po <= 0 THEN 'Belum PO sama sekali' - WHEN qty_po < qty_so THEN 'Belum PO full' + WHEN qty_reserved < qty_so and qty_reserved > 0 THEN 'Belum PO full' + WHEN qty_reserved = qty_so THEN 'Belum PO sama sekali' WHEN qty_po_received < qty_so and qty_po_received <= 0 THEN 'Belum Received sama sekali' WHEN qty_po_received < qty_so THEN 'Belum Received full' WHEN qty_to_delivered = qty_so THEN 'SIAP KIRIM' @@ -52,7 +55,8 @@ class SaleMonitoringDetail(models.Model): sol.qty_invoiced AS qty_so_invoiced, so.date_order AS date_order, get_qty_po(so.id, sol.product_id) AS qty_po, - get_qty_received(so.id, sol.product_id) AS qty_po_received + get_qty_received(so.id, sol.product_id) AS qty_po_received, + get_qty_reserved(so.id, sol.product_id) as qty_reserved FROM sale_order so JOIN sale_order_line sol ON sol.order_id = so.id JOIN product_product p ON p.id = sol.product_id -- cgit v1.2.3 From 64507a0c199721fee5e3fc8c808adec5a3ee6a5d Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 15 Jun 2023 11:54:20 +0700 Subject: revert code nathan --- indoteknik_custom/models/purchase_order.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index ea75539a..7e18bd8f 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -151,10 +151,11 @@ class PurchaseOrder(models.Model): self.order_line.unlink() for order_line in self.sale_order_id.order_line: if order_line.product_id.id and order_line.product_id.id not in products_exception: - qty_available = self.env['stock.quant'].search([ - ('product_id', '=', order_line.product_id.id), - ('location_id', '=', "BU/Stock") - ], limit=1) + # qty_available = self.env['stock.quant'].search([ + # ('product_id', '=', order_line.product_id.id), + # ('location_id', '=', "BU/Stock") + # ], limit=1) + qty_available = order_line.product_id.virtual_available suggest = 'harus beli' if order_line.product_id.virtual_available > order_line.product_qty: suggest = 'masih cukup' @@ -163,10 +164,10 @@ class PurchaseOrder(models.Model): 'product_id': order_line.product_id.id, 'name': order_line.product_id.display_name, 'product_qty': order_line.product_qty, - 'qty_available_store': qty_available.available_quantity, + 'qty_available_store': qty_available, 'suggest': suggest, } - self.order_line.create(values) + self.env['purchase.order.line'].sudo().create(values) def compute_count_line_product(self): for order in self: -- cgit v1.2.3 From d32accf86a2baffcf7ce90554d1f8868ab518cf4 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 15 Jun 2023 15:07:24 +0700 Subject: change logic of sales monitoring --- indoteknik_custom/models/sale_monitoring.py | 16 ++++++---------- indoteknik_custom/models/sale_monitoring_detail.py | 16 ++++++---------- 2 files changed, 12 insertions(+), 20 deletions(-) (limited to 'indoteknik_custom/models') diff --git a/indoteknik_custom/models/sale_monitoring.py b/indoteknik_custom/models/sale_monitoring.py index ea1e490c..e79ff9ab 100755 --- a/indoteknik_custom/models/sale_monitoring.py +++ b/indoteknik_custom/models/sale_monitoring.py @@ -39,16 +39,12 @@ class SaleMonitoring(models.Model): SUM(smd.qty_so_invoiced) AS qty_so_invoiced, sum(smd.qty_reserved) as qty_reserved, CASE - WHEN SUM(qty_so) = SUM(qty_reserved) then 'SIAP KIRIM' - WHEN SUM(qty_so) = SUM(qty_so_delivered) then 'Delivered' - WHEN SUM(qty_so) = SUM(qty_so_invoiced) then 'Done' - WHEN SUM(qty_reserved) < SUM(qty_so) and SUM(qty_reserved) > 0 THEN 'Belum PO full' - WHEN SUM(qty_reserved) = SUM(qty_so) THEN 'Belum PO sama sekali' - WHEN SUM(qty_po_received) < SUM(qty_so) AND SUM(qty_po_received) <= 0 THEN 'Belum Received sama sekali' - WHEN SUM(qty_po_received) < SUM(qty_so) THEN 'Belum Received full' - WHEN SUM(qty_to_delivered) = SUM(qty_so) THEN 'SIAP KIRIM' - WHEN SUM(qty_to_delivered) < SUM(qty_so) and SUM(qty_to_delivered) > 0 THEN 'KIRIM SISANYA' - ELSE 'Belum Invoiced' + when sum(qty_so_invoiced) = sum(qty_so) then 'Invoiced' + when sum(qty_so_delivered) = sum(qty_so) then 'Delivered' + when sum(qty_reserved) >= sum(qty_so) then 'Siap kirim' + when sum(qty_po) + sum(qty_reserved) - sum(qty_po_received) < sum(qty_so) then 'Belum/Kurang PO' + when sum(qty_po_received) = 0 then 'Belum terima' + when sum(qty_po_received) < sum(qty_po) then 'Terima sebagian' END AS status, get_po_number(smd.sale_order_id) as po_number FROM sale_monitoring_detail smd diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py index 908ccb68..2bcda50c 100755 --- a/indoteknik_custom/models/sale_monitoring_detail.py +++ b/indoteknik_custom/models/sale_monitoring_detail.py @@ -30,16 +30,12 @@ class SaleMonitoringDetail(models.Model): SELECT *, CASE - WHEN qty_so = qty_reserved then 'SIAP KIRIM' - WHEN qty_so = qty_so_delivered then 'Delivered' - WHEN qty_so = qty_so_invoiced then 'Done' - WHEN qty_reserved < qty_so and qty_reserved > 0 THEN 'Belum PO full' - WHEN qty_reserved = qty_so THEN 'Belum PO sama sekali' - WHEN qty_po_received < qty_so and qty_po_received <= 0 THEN 'Belum Received sama sekali' - WHEN qty_po_received < qty_so THEN 'Belum Received full' - WHEN qty_to_delivered = qty_so THEN 'SIAP KIRIM' - WHEN qty_to_delivered < qty_so and qty_to_delivered > 0 THEN 'KIRIM SISANYA' - ELSE 'Belum Invoiced' + when qty_so_invoiced = qty_so then 'Invoiced' + when qty_so_delivered = qty_so then 'Delivered' + when qty_reserved >= qty_so then 'Siap kirim' + when qty_po + qty_reserved - qty_po_received < qty_so then 'Belum/Kurang PO' + when qty_po_received = 0 then 'Belum terima' + when qty_po_received < qty_po then 'Terima sebagian' END AS status FROM ( -- cgit v1.2.3