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(-) 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(-) 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/__manifest__.py | 1 + indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/automatic_purchase.py | 2 +- indoteknik_custom/models/requisition.py | 179 +++++++++++++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 5 +- indoteknik_custom/views/ir_sequence.xml | 10 ++ indoteknik_custom/views/requisition.xml | 101 ++++++++++++++ 7 files changed, 297 insertions(+), 2 deletions(-) create mode 100644 indoteknik_custom/models/requisition.py create mode 100644 indoteknik_custom/views/requisition.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index c52e27b7..e1c2ec7b 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -74,6 +74,7 @@ 'views/procurement_monitoring_detail.xml', 'views/product_product.xml', 'views/brand_vendor.xml', + 'views/requisition.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', 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 diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 39504393..26e852f1 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -48,4 +48,7 @@ access_apache_solr,access.apache.solr,model_apache_solr,,1,1,1,1 access_group_partner,access.group.partner,model_group_partner,,1,1,1,1 access_procurement_monitoring_detail,access.procurement.monitoring.detail,model_procurement_monitoring_detail,,1,1,1,1 access_rajaongkir_kurir,access.rajaongkir.kurir,model_rajaongkir_kurir,,1,1,1,1 -access_brand_vendor,access.brand.vendor,model_brand_vendor,,1,1,1,1 \ No newline at end of file +access_brand_vendor,access.brand.vendor,model_brand_vendor,,1,1,1,1 +access_requisition,access.requisition,model_requisition,,1,1,1,1 +access_requisition_line,access.requisition.line,model_requisition_line,,1,1,1,1 +access_requisition_purchase_match,access.requisition.purchase.match,model_requisition_purchase_match,,1,1,1,1 \ No newline at end of file diff --git a/indoteknik_custom/views/ir_sequence.xml b/indoteknik_custom/views/ir_sequence.xml index 6a6f474d..9af85408 100644 --- a/indoteknik_custom/views/ir_sequence.xml +++ b/indoteknik_custom/views/ir_sequence.xml @@ -30,5 +30,15 @@ 1 1 + + + Requisition + requisition + TRUE + RPO/%(year)s/ + 5 + 1 + 1 + \ No newline at end of file diff --git a/indoteknik_custom/views/requisition.xml b/indoteknik_custom/views/requisition.xml new file mode 100644 index 00000000..6e61ce1e --- /dev/null +++ b/indoteknik_custom/views/requisition.xml @@ -0,0 +1,101 @@ + + + + requisition.tree + requisition + + + + + + + + + + + + + requisition.line.tree + requisition.line + + + + + + + + + + + + + + + + requisition.purchase.match.tree + requisition.purchase.match + + + + + + + + + + + requisition.form + requisition + +
+ +
+ + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + Requisition + ir.actions.act_window + requisition + tree,form + + + + \ No newline at end of file -- 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_api/models/product_product.py | 2 +- indoteknik_custom/models/apache_solr.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/models/product_product.py b/indoteknik_api/models/product_product.py index 49ea7804..7913e37e 100644 --- a/indoteknik_api/models/product_product.py +++ b/indoteknik_api/models/product_product.py @@ -139,7 +139,7 @@ class ProductProduct(models.Model): default_divide_tax = float(1.11) price_after_disc = self._get_website_price_after_disc() res = price_after_disc / default_divide_tax - res = math.floor(res) + res = math.ceil(res) return res def _get_website_price_after_disc(self): 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 +++++ indoteknik_custom/views/sale_order.xml | 5 +++++ 3 files changed, 43 insertions(+) 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([ diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index c66201a9..2fcef922 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -82,6 +82,11 @@ + - - + + -- 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(-) 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 ++++ indoteknik_custom/views/stock_picking.xml | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) 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. diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index e4e9f722..4bbdc7b8 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -7,10 +7,11 @@ - - - - + + + + + @@ -80,6 +81,7 @@ + -- 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(-) 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(-) 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 +++++++--- indoteknik_custom/views/sale_monitoring.xml | 6 ++++-- indoteknik_custom/views/sale_monitoring_detail.xml | 6 ++++-- 4 files changed, 22 insertions(+), 9 deletions(-) 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 diff --git a/indoteknik_custom/views/sale_monitoring.xml b/indoteknik_custom/views/sale_monitoring.xml index b3b186e9..fffd140f 100755 --- a/indoteknik_custom/views/sale_monitoring.xml +++ b/indoteknik_custom/views/sale_monitoring.xml @@ -13,6 +13,7 @@ + @@ -22,7 +23,7 @@ decoration-danger="status == 'Belum PO sama sekali' or status == 'Belum PO full'" decoration-warning="status == 'Belum Received sama sekali' or status == 'Belum Received full'" decoration-success="status == 'SIAP KIRIM' or status == 'KIRIM SISANYA'" - decoration-info="status == 'Belum Invoiced'" + decoration-info="status == 'Belum Invoiced' or status == 'Done' or status == 'Delivered'" /> @@ -44,12 +45,13 @@ decoration-danger="status == 'Belum PO sama sekali' or status == 'Belum PO full'" decoration-warning="status == 'Belum Received sama sekali' or status == 'Belum Received full'" decoration-success="status == 'SIAP KIRIM' or status == 'KIRIM SISANYA'" - decoration-info="status == 'Belum Invoiced'" + decoration-info="status == 'Belum Invoiced' or status == 'Done' or status == 'Delivered'" /> + diff --git a/indoteknik_custom/views/sale_monitoring_detail.xml b/indoteknik_custom/views/sale_monitoring_detail.xml index b9602abd..78bb92c7 100755 --- a/indoteknik_custom/views/sale_monitoring_detail.xml +++ b/indoteknik_custom/views/sale_monitoring_detail.xml @@ -11,6 +11,7 @@ + @@ -20,7 +21,7 @@ decoration-danger="status == 'Belum PO sama sekali' or status == 'Belum PO full'" decoration-warning="status == 'Belum Received sama sekali' or status == 'Belum Received full'" decoration-success="status == 'SIAP KIRIM' or status == 'KIRIM SISANYA'" - decoration-info="status == 'Belum Invoiced' or status == 'Done'" + decoration-info="status == 'Belum Invoiced' or status == 'Done' or status == 'Delivered'" /> @@ -43,11 +44,12 @@ decoration-danger="status == 'Belum PO sama sekali' or status == 'Belum PO full'" decoration-warning="status == 'Belum Received sama sekali' or status == 'Belum Received full'" decoration-success="status == 'SIAP KIRIM' or status == 'KIRIM SISANYA'" - decoration-info="status == 'Belum Invoiced'" + decoration-info="status == 'Belum Invoiced' or status == 'Done' or status == 'Delivered'" /> + -- 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(-) 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 ++++++---------- indoteknik_custom/views/sale_monitoring.xml | 16 ++++++++-------- indoteknik_custom/views/sale_monitoring_detail.xml | 16 ++++++++-------- 4 files changed, 28 insertions(+), 36 deletions(-) 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 ( diff --git a/indoteknik_custom/views/sale_monitoring.xml b/indoteknik_custom/views/sale_monitoring.xml index fffd140f..956e4a24 100755 --- a/indoteknik_custom/views/sale_monitoring.xml +++ b/indoteknik_custom/views/sale_monitoring.xml @@ -20,10 +20,10 @@ @@ -42,10 +42,10 @@ diff --git a/indoteknik_custom/views/sale_monitoring_detail.xml b/indoteknik_custom/views/sale_monitoring_detail.xml index 78bb92c7..736920b3 100755 --- a/indoteknik_custom/views/sale_monitoring_detail.xml +++ b/indoteknik_custom/views/sale_monitoring_detail.xml @@ -18,10 +18,10 @@ @@ -41,10 +41,10 @@ -- cgit v1.2.3 From 24649f8e939484759ef34e5e68f251d951f63c02 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 15 Jun 2023 15:41:18 +0700 Subject: paid if using midtrans --- indoteknik_api/models/account_move.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/indoteknik_api/models/account_move.py b/indoteknik_api/models/account_move.py index 54e06f84..23a7076c 100644 --- a/indoteknik_api/models/account_move.py +++ b/indoteknik_api/models/account_move.py @@ -6,6 +6,10 @@ class AccountMove(models.Model): _inherit = 'account.move' def api_v1_single_response(self, account_move, context=False): + sale_order = self.env['sale.order'].search([('name', '=', account_move.invoice_origin), ('state', '=', 'done')], limit=1) + amount_residual = account_move.amount_residual + if sale_order.payment_status == 'settlement' or sale_order.payment_status == 'capture': + amount_residual = 0 data = { 'token': self.env['rest.api'].md5_salt(account_move.id, 'account.move'), 'id': account_move.id, @@ -14,7 +18,7 @@ class AccountMove(models.Model): 'payment_term': account_move.invoice_payment_term_id.name or '', 'sales': account_move.invoice_user_id.name, 'amount_total': account_move.amount_total, - 'amount_residual': account_move.amount_residual, + 'amount_residual': amount_residual, 'invoice_date': account_move.invoice_date.strftime('%d/%m/%Y') or '', 'efaktur': True if account_move.efaktur_document else False, } @@ -30,7 +34,7 @@ class AccountMove(models.Model): 'payment_term': account_move.invoice_payment_term_id.name or '', 'sales': account_move.invoice_user_id.name, 'amount_total': account_move.amount_total, - 'amount_residual': account_move.amount_residual, + 'amount_residual': amount_residual, 'invoice_date_due': account_move.invoice_date_due.strftime('%d/%m/%Y') or '', 'customer': res_users.api_address_response(account_move.partner_id), 'products': [], -- cgit v1.2.3