diff options
| -rw-r--r-- | indoteknik_api/controllers/api_v1/stock_picking.py | 102 | ||||
| -rw-r--r-- | indoteknik_api/models/sale_order.py | 2 | ||||
| -rw-r--r-- | indoteknik_custom/models/manufacturing.py | 3 | ||||
| -rwxr-xr-x | indoteknik_custom/models/product_template.py | 2 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 26 | ||||
| -rw-r--r-- | indoteknik_custom/models/requisition.py | 14 | ||||
| -rw-r--r-- | indoteknik_custom/models/res_partner.py | 352 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 4 | ||||
| -rw-r--r-- | indoteknik_custom/models/sale_order_line.py | 87 | ||||
| -rw-r--r-- | indoteknik_custom/models/shipment_group.py | 12 | ||||
| -rw-r--r-- | indoteknik_custom/models/stock_picking.py | 25 |
11 files changed, 340 insertions, 289 deletions
diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py index 31706b99..49547779 100644 --- a/indoteknik_api/controllers/api_v1/stock_picking.py +++ b/indoteknik_api/controllers/api_v1/stock_picking.py @@ -22,42 +22,44 @@ class StockPicking(controller.Controller): if not get_params['valid']: return self.response(code=400, description=get_params) - + params = get_params['value'] partner_id = params['partner_id'] limit = params['limit'] offset = params['offset'] - + child_ids = request.env['res.partner'].browse(partner_id).get_child_ids() pending_domain = [('driver_departure_date', '=', False), ('driver_arrival_date', '=', False)] shipment_domain = [('driver_departure_date', '!=', False), ('driver_arrival_date', '=', False)] shipment_domain2 = [('driver_departure_date', '!=', False), ('sj_return_date', '=', False)] - completed_domain = [('driver_departure_date', '!=', False),'|', ('driver_arrival_date', '!=', False), ('sj_return_date', '!=', False)] + completed_domain = [('driver_departure_date', '!=', False), '|', ('driver_arrival_date', '!=', False), + ('sj_return_date', '!=', False)] completed_domain2 = [('driver_departure_date', '!=', False), ('sj_return_date', '!=', False)] picking_model = request.env['stock.picking'] domain = [ - ('partner_id', 'in', child_ids), - ('sale_id', '!=', False), - ('origin', 'ilike', 'SO%'), - ('state', '!=', 'cancel') + ('partner_id', 'in', child_ids), + ('sale_id', '!=', False), + ('origin', 'ilike', 'SO%'), + ('state', '!=', 'cancel'), + ('name', 'ilike', 'BU/OUT%') ] - + if params['q']: query_like = '%' + params['q'].replace(' ', '%') + '%' - domain += ['|', '|', - ('name', 'ilike', query_like), - ('sale_id.client_order_ref', 'ilike', query_like), - ('delivery_tracking_no', 'ilike', query_like) - ] + domain += ['|', '|', + ('name', 'ilike', query_like), + ('sale_id.client_order_ref', 'ilike', query_like), + ('delivery_tracking_no', 'ilike', query_like) + ] default_domain = domain.copy() - + if params['status'] == 'pending': domain += pending_domain elif params['status'] == 'shipment': - domain += shipment_domain + shipment_domain2 + domain += shipment_domain + shipment_domain2 elif params['status'] == 'completed': domain += completed_domain @@ -65,7 +67,7 @@ class StockPicking(controller.Controller): res_pickings = [] for picking in stock_pickings: manifests = picking.get_manifests() - + res_pickings.append({ 'id': picking.id, 'name': picking.name, @@ -86,12 +88,12 @@ class StockPicking(controller.Controller): 'summary': { 'pending_count': picking_model.search_count(default_domain + pending_domain), 'shipment_count': picking_model.search_count(default_domain + shipment_domain + shipment_domain2), - 'completed_count': picking_model.search_count(default_domain + completed_domain ) + 'completed_count': picking_model.search_count(default_domain + completed_domain) }, 'picking_total': picking_model.search_count(domain), 'pickings': res_pickings }) - + @http.route(PREFIX_PARTNER + 'stock-picking/<id>/tracking', auth='public', method=['GET', 'OPTIONS']) @controller.Controller.must_authorized(private=True, private_key='partner_id') def get_partner_stock_picking_detail_tracking(self, **kw): @@ -140,37 +142,43 @@ class StockPicking(controller.Controller): return self.response({ 'name': picking_data.name }) - - @http.route(prefix + 'webhook/biteship', type='json', auth='public', methods=['POST'], csrf=False) + + # @http.route(prefix + 'webhook/biteship', type='json', auth='public', methods=['POST'], csrf=False) + # def udpate_status_from_bitehsip(self, **kw): + # try: + # if not request.jsonrequest: + # return "ok" + + # data = request.jsonrequest # Ambil data JSON dari request + # event = data.get('event') + + # # Handle Event Berdasarkan Jenisnya + # if event == "order.status": + # self.process_order_status(data) + # elif event == "order.price": + # self.process_order_price(data) + # elif event == "order.waybill_id": + # self.process_order_waybill(data) + + # return {'success': True, 'message': f'Webhook {event} received'} + # except Exception as e: + # return {'success': False, 'message': str(e)} + + @http.route(prefix + 'webhook/biteship', type='json', auth='public', methods=['POST'], csrf=False) def udpate_status_from_bitehsip(self, **kw): - try: - if not request.jsonrequest: - return "ok" - - data = request.jsonrequest # Ambil data JSON dari request - event = data.get('event') - - # Handle Event Berdasarkan Jenisnya - if event == "order.status": - self.process_order_status(data) - elif event == "order.price": - self.process_order_price(data) - elif event == "order.waybill_id": - self.process_order_waybill(data) - - return {'success': True, 'message': f'Webhook {event} received'} - except Exception as e: - return {'success': False, 'message': str(e)} + return "ok" def process_order_status(self, data): - picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], limit=1) + picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], + limit=1) if data.get('status') == 'picked': picking_model.write({'driver_departure_date': datetime.utcnow()}) elif data.get('status') == 'delivered': picking_model.write({'driver_arrival_date': datetime.utcnow()}) - + def process_order_price(self, data): - picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], limit=1) + picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], + limit=1) order = request.env['sale.order'].sudo().search([('name', '=', picking_model.sale_id.name)], limit=1) if order: order.write({ @@ -178,11 +186,11 @@ class StockPicking(controller.Controller): }) def process_order_waybill(self, data): - picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], limit=1) + picking_model = request.env['stock.picking'].sudo().search([('biteship_id', '=', data.get('order_id'))], + limit=1) if picking_model: picking_model.write({ - 'biteship_waybill_id': data.get('courier_waybill_id'), - 'delivery_tracking_no': data.get('courier_waybill_id'), - 'biteship_tracking_id':data.get('courier_tracking_id') - }) -
\ No newline at end of file + 'biteship_waybill_id': data.get('courier_waybill_id'), + 'delivery_tracking_no': data.get('courier_waybill_id'), + 'biteship_tracking_id': data.get('courier_tracking_id') + }) diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 727379c5..baba7c37 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -29,6 +29,8 @@ class SaleOrder(models.Model): 'pickings': [] } for picking in sale_order.picking_ids: + if not picking.name.startswith('BU/OUT'): + continue data['pickings'].append({ 'id': picking.id, 'name': picking.name, diff --git a/indoteknik_custom/models/manufacturing.py b/indoteknik_custom/models/manufacturing.py index 715d8513..aea01362 100644 --- a/indoteknik_custom/models/manufacturing.py +++ b/indoteknik_custom/models/manufacturing.py @@ -11,6 +11,9 @@ class Manufacturing(models.Model): def action_confirm(self): if self._name != 'mrp.production': return super(Manufacturing, self).action_confirm() + + if not self.env.user.is_purchasing_manager: + raise UserError("Hanya bisa di confirm oleh Purchasing Manager") # if self.location_src_id.id != 75: # raise UserError('Component Location hanya bisa di AS/Stock') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 3bb54f44..2c07824a 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -1146,7 +1146,7 @@ class ProductProduct(models.Model): def _get_qty_free_bandengan(self): for product in self: - qty_free = product.qty_onhand_bandengan - product.qty_outgoing_bandengan + qty_free = product.qty_onhand_bandengan - product.qty_outgoing_bandengan - product.qty_outgoing_mo_bandengan product.qty_free_bandengan = qty_free def _get_max_qty_reordering_rule(self): diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index cbfd4acd..21ca55eb 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -808,8 +808,8 @@ class PurchaseOrder(models.Model): # test = line.product_uom_qty # test2 = line.product_id.plafon_qty # test3 = test2 + line.product_uom_qty - if line.product_uom_qty > line.product_id.plafon_qty + line.product_uom_qty and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): - raise UserError('Product '+line.product_id.name+' melebihi plafon, harus Approval MD') + if line.product_uom_qty > line.product_id.plafon_qty + line.product_uom_qty and not self.env.user.id == 21: + raise UserError('Product '+line.product_id.name+' melebihi plafon, harus Approval Rafly') def check_different_vendor_so_po(self): vendor_po = self.partner_id.id @@ -817,7 +817,11 @@ class PurchaseOrder(models.Model): if not line.so_line_id: continue if line.so_line_id.vendor_id.id != vendor_po and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): - raise UserError("Produk "+line.product_id.name+" memiliki vendor berbeda dengan SO (Vendor PO: "+str(self.partner_id.name)+", Vendor SO: "+str(line.so_line_id.vendor_id.name)+")") + self.env.user.notify_danger( + title='WARNING!!!', + message="Produk "+line.product_id.name+" memiliki vendor berbeda dengan SO (Vendor PO: "+str(self.partner_id.name)+", Vendor SO: "+str(line.so_line_id.vendor_id.name)+")", + sticky=True + ) def button_confirm(self): # self._check_payment_term() # check payment term @@ -837,16 +841,16 @@ class PurchaseOrder(models.Model): sticky=True ) - if len(self.order_sales_match_line) == 0 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: - self.env.user.notify_danger( - title='WARNING!!!', - message='Tidak ada matches SO', - sticky=True - ) + # if len(self.order_sales_match_line) == 0 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: + # self.env.user.notify_danger( + # title='WARNING!!!', + # message='Tidak ada matches SO', + # sticky=True + # ) if not self.from_apo: - if not self.matches_so and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: - raise UserError("Tidak ada link dengan SO, harus approval Merchandise") + if not self.matches_so and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: + raise UserError("Tidak ada link dengan SO, harus di confirm oleh Purchasing Manager") send_email = False if not self.not_update_purchasepricelist: diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 74236850..25133e72 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -82,20 +82,20 @@ class Requisition(models.Model): state = ['done', 'sale'] if self.sale_order_id.state in state: raise UserError('SO sudah Confirm, akan berakibat double Purchase melalui PJ') - if self.env.user.id not in [377, 19, 28]: - raise UserError('Hanya Vita dan Darren Yang Bisa Approve') - if self.env.user.id == 377 or self.env.user.id == 28: + if self.env.user.id not in [21, 19, 28]: + raise UserError('Hanya Rafly dan Darren Yang Bisa Approve') + if self.env.user.id == 19 or self.env.user.id == 28: self.sales_approve = True - elif self.env.user.id == 19 or self.env.user.id == 28: + elif self.env.user.id == 21 or self.env.user.id == 28: if not self.sales_approve: - raise UserError('Vita Belum Approve') + raise UserError('Darren Belum Approve') self.merchandise_approve = True def create_po_from_requisition(self): if not self.sales_approve: - raise UserError('Harus Di Approve oleh Vita') - if not self.merchandise_approve: raise UserError('Harus Di Approve oleh Darren') + if not self.merchandise_approve: + raise UserError('Harus Di Approve oleh Rafly') if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 191a44c9..f1e362e6 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -235,182 +235,182 @@ class ResPartner(models.Model): raise ValidationError("Digit NPWP yang dimasukkan tidak sesuai. Pastikan NPWP memiliki 15 digit dengan format tertentu (99.999.999.9-999.999) atau 16 digit tanpa tanda hubung.") - def write(self, vals): - # Fungsi rekursif untuk meng-update semua child, termasuk child dari child - def update_children_recursively(partner, vals_for_child): - # Lakukan update pada partner saat ini hanya dengan field yang diizinkan - partner.write(vals_for_child) - - # Untuk setiap child dari partner ini, update juga child-nya - for child in partner.child_ids: - update_children_recursively(child, vals_for_child) - - # Jika self tidak memiliki parent_id, artinya self adalah parent - if not self.parent_id: - # Ambil semua child dari parent ini - children = self.child_ids - - # Perbarui vals dengan nilai dari parent jika tidak ada dalam vals - vals['customer_type'] = vals.get('customer_type', self.customer_type) - vals['nama_wajib_pajak'] = vals.get('nama_wajib_pajak', self.nama_wajib_pajak) - vals['npwp'] = vals.get('npwp', self.npwp) - vals['sppkp'] = vals.get('sppkp', self.sppkp) - vals['alamat_lengkap_text'] = vals.get('alamat_lengkap_text', self.alamat_lengkap_text) - vals['industry_id'] = vals.get('industry_id', self.industry_id.id if self.industry_id else None) - vals['company_type_id'] = vals.get('company_type_id', self.company_type_id.id if self.company_type_id else None) - - # Referensi - vals['supplier_ids'] = vals.get('supplier_ids', self.supplier_ids) - - # informasi perusahaan - vals['name_tempo'] = vals.get('name_tempo', self.name_tempo) - vals['industry_id_tempo'] = vals.get('industry_id_tempo', self.industry_id_tempo) - vals['street_tempo'] = vals.get('street_tempo', self.street_tempo) - vals['state_id_tempo'] = vals.get('state_id_tempo', self.state_id_tempo) - vals['city_id_tempo'] = vals.get('city_id_tempo', self.city_id_tempo) - vals['zip_tempo'] = vals.get('zip_tempo', self.zip_tempo) - vals['bank_name_tempo'] = vals.get('bank_name_tempo', self.bank_name_tempo) - vals['account_name_tempo'] = vals.get('account_name_tempo', self.account_name_tempo) - vals['account_number_tempo'] = vals.get('account_number_tempo', self.account_number_tempo) - vals['website_tempo'] = vals.get('website_tempo', self.website_tempo) - vals['portal'] = vals.get('portal', self.portal) - vals['estimasi_tempo'] = vals.get('estimasi_tempo', self.estimasi_tempo) - vals['tempo_duration'] = vals.get('tempo_duration', self.tempo_duration) - vals['tempo_limit'] = vals.get('tempo_limit', self.tempo_limit) - vals['category_produk_ids'] = vals.get('category_produk_ids', self.category_produk_ids) - - # Kontak Perusahaan - vals['direktur_name'] = vals.get('direktur_name', self.direktur_name) - vals['direktur_mobile'] = vals.get('direktur_mobile', self.direktur_mobile) - vals['direktur_email'] = vals.get('direktur_email', self.direktur_email) - vals['purchasing_name'] = vals.get('purchasing_name', self.purchasing_name) - vals['purchasing_mobile'] = vals.get('purchasing_mobile', self.purchasing_mobile) - vals['purchasing_email'] = vals.get('purchasing_email', self.purchasing_email) - vals['finance_name'] = vals.get('finance_name', self.finance_name) - vals['finance_mobile'] = vals.get('finance_mobile', self.finance_mobile) - vals['finance_email'] = vals.get('finance_email', self.finance_email) - - # Pengiriman - vals['pic_name'] = vals.get('pic_name', self.pic_name) - vals['pic_mobile'] = vals.get('pic_mobile', self.pic_mobile) - vals['street_pengiriman'] = vals.get('street_pengiriman', self.street_pengiriman) - vals['state_id_pengiriman'] = vals.get('state_id_pengiriman', self.state_id_pengiriman) - vals['city_id_pengiriman'] = vals.get('city_id_pengiriman', self.city_id_pengiriman) - vals['district_id_pengiriman'] = vals.get('district_id_pengiriman', self.district_id_pengiriman) - vals['subDistrict_id_pengiriman'] = vals.get('subDistrict_id_pengiriman', self.subDistrict_id_pengiriman) - vals['zip_pengiriman'] = vals.get('zip_pengiriman', self.zip_pengiriman) - vals['invoice_pic'] = vals.get('invoice_pic', self.invoice_pic) - vals['invoice_pic_mobile'] = vals.get('invoice_pic_mobile', self.invoice_pic_mobile) - vals['street_invoice'] = vals.get('street_invoice', self.street_invoice) - vals['state_id_invoice'] = vals.get('state_id_invoice', self.state_id_invoice) - vals['city_id_invoice'] = vals.get('city_id_invoice', self.city_id_invoice) - vals['district_id_invoice'] = vals.get('district_id_invoice', self.district_id_invoice) - vals['subDistrict_id_invoice'] = vals.get('subDistrict_id_invoice', self.subDistrict_id_invoice) - vals['zip_invoice'] = vals.get('zip_invoice', self.zip_invoice) - vals['tukar_invoice'] = vals.get('tukar_invoice', self.tukar_invoice) - vals['jadwal_bayar'] = vals.get('jadwal_bayar', self.jadwal_bayar) - vals['dokumen_prosedur'] = vals.get('dokumen_prosedur', self.dokumen_prosedur) - vals['dokumen_pengiriman'] = vals.get('dokumen_pengiriman', self.dokumen_pengiriman) - vals['dokumen_pengiriman_input'] = vals.get('dokumen_pengiriman_input', self.dokumen_pengiriman_input) - vals['dokumen_invoice'] = vals.get('dokumen_invoice', self.dokumen_invoice) - - # Dokumen - vals['dokumen_npwp'] = vals.get('dokumen_npwp', self.dokumen_npwp) - vals['dokumen_sppkp'] = vals.get('dokumen_sppkp', self.dokumen_sppkp) - vals['dokumen_nib'] = vals.get('dokumen_nib', self.dokumen_nib) - vals['dokumen_siup'] = vals.get('dokumen_siup', self.dokumen_siup) - vals['dokumen_tdp'] = vals.get('dokumen_tdp', self.dokumen_tdp) - vals['dokumen_skdp'] = vals.get('dokumen_skdp', self.dokumen_skdp) - vals['dokumen_skt'] = vals.get('dokumen_skt', self.dokumen_skt) - vals['dokumen_akta_perubahan'] = vals.get('dokumen_akta_perubahan', self.dokumen_akta_perubahan) - vals['dokumen_ktp_dirut'] = vals.get('dokumen_ktp_dirut', self.dokumen_ktp_dirut) - vals['dokumen_akta_pendirian'] = vals.get('dokumen_akta_pendirian', self.dokumen_akta_pendirian) - vals['dokumen_laporan_keuangan'] = vals.get('dokumen_laporan_keuangan', self.dokumen_laporan_keuangan) - vals['dokumen_foto_kantor'] = vals.get('dokumen_foto_kantor', self.dokumen_foto_kantor) - vals['dokumen_tempat_bekerja'] = vals.get('dokumen_tempat_bekerja', self.dokumen_tempat_bekerja) - - # Simpan hanya field yang perlu di-update pada child - vals_for_child = { - 'customer_type': vals.get('customer_type'), - 'nama_wajib_pajak': vals.get('nama_wajib_pajak'), - 'npwp': vals.get('npwp'), - 'sppkp': vals.get('sppkp'), - 'alamat_lengkap_text': vals.get('alamat_lengkap_text'), - 'industry_id': vals.get('industry_id'), - 'company_type_id': vals.get('company_type_id'), - 'supplier_ids': vals.get('supplier_ids'), - 'name_tempo': vals.get('name_tempo'), - 'industry_id_tempo': vals.get('industry_id_tempo'), - 'street_tempo': vals.get('street_tempo'), - 'state_id_tempo': vals.get('state_id_tempo'), - 'city_id_tempo': vals.get('city_id_tempo'), - 'zip_tempo': vals.get('zip_tempo'), - 'bank_name_tempo': vals.get('bank_name_tempo'), - 'account_name_tempo': vals.get('account_name_tempo'), - 'account_number_tempo': vals.get('account_number_tempo'), - 'website_tempo': vals.get('website_tempo'), - 'portal': vals.get('portal'), - 'estimasi_tempo': vals.get('estimasi_tempo'), - 'tempo_duration': vals.get('tempo_duration'), - 'tempo_limit': vals.get('tempo_limit'), - 'category_produk_ids': vals.get('category_produk_ids'), - 'direktur_name': vals.get('direktur_name'), - 'direktur_mobile': vals.get('direktur_mobile'), - 'direktur_email': vals.get('direktur_email'), - 'purchasing_name': vals.get('purchasing_name'), - 'purchasing_mobile': vals.get('purchasing_mobile'), - 'purchasing_email': vals.get('purchasing_email'), - 'finance_name': vals.get('finance_name'), - 'finance_mobile': vals.get('finance_mobile'), - 'finance_email': vals.get('finance_email'), - 'pic_name': vals.get('pic_name'), - 'pic_mobile': vals.get('pic_mobile'), - 'street_pengiriman': vals.get('street_pengiriman'), - 'state_id_pengiriman': vals.get('state_id_pengiriman'), - 'city_id_pengiriman': vals.get('city_id_pengiriman'), - 'district_id_pengiriman': vals.get('district_id_pengiriman'), - 'subDistrict_id_pengiriman': vals.get('subDistrict_id_pengiriman'), - 'zip_pengiriman': vals.get('zip_pengiriman'), - 'invoice_pic': vals.get('invoice_pic'), - 'invoice_pic_mobile': vals.get('invoice_pic_mobile'), - 'street_invoice': vals.get('street_invoice'), - 'state_id_invoice': vals.get('state_id_invoice'), - 'city_id_invoice': vals.get('city_id_invoice'), - 'district_id_invoice': vals.get('district_id_invoice'), - 'subDistrict_id_invoice': vals.get('subDistrict_id_invoice'), - 'zip_invoice': vals.get('zip_invoice'), - 'tukar_invoice': vals.get('tukar_invoice'), - 'jadwal_bayar': vals.get('jadwal_bayar'), - 'dokumen_prosedur': vals.get('dokumen_prosedur'), - 'dokumen_pengiriman': vals.get('dokumen_pengiriman'), - 'dokumen_pengiriman_input': vals.get('dokumen_pengiriman_input'), - 'dokumen_invoice': vals.get('dokumen_invoice'), - 'dokumen_npwp': vals.get('dokumen_npwp'), - 'dokumen_sppkp': vals.get('dokumen_sppkp'), - 'dokumen_nib': vals.get('dokumen_nib'), - 'dokumen_siup': vals.get('dokumen_siup'), - 'dokumen_tdp': vals.get('dokumen_tdp'), - 'dokumen_skdp': vals.get('dokumen_skdp'), - 'dokumen_skt': vals.get('dokumen_skt'), - 'dokumen_akta_perubahan': vals.get('dokumen_akta_perubahan'), - 'dokumen_ktp_dirut': vals.get('dokumen_ktp_dirut'), - 'dokumen_akta_pendirian': vals.get('dokumen_akta_pendirian'), - 'dokumen_laporan_keuangan': vals.get('dokumen_laporan_keuangan'), - 'dokumen_foto_kantor': vals.get('dokumen_foto_kantor'), - 'dokumen_tempat_bekerja': vals.get('dokumen_tempat_bekerja'), - - # internal_notes - 'comment': vals.get('comment') - } - - # Lakukan update pada semua child secara rekursif - for child in children: - update_children_recursively(child, vals_for_child) - - # Lakukan write untuk parent dengan vals asli - res = super(ResPartner, self).write(vals) - - return res + # def write(self, vals): + # # Fungsi rekursif untuk meng-update semua child, termasuk child dari child + # def update_children_recursively(partner, vals_for_child): + # # Lakukan update pada partner saat ini hanya dengan field yang diizinkan + # partner.write(vals_for_child) + # + # # Untuk setiap child dari partner ini, update juga child-nya + # for child in partner.child_ids: + # update_children_recursively(child, vals_for_child) + # + # # Jika self tidak memiliki parent_id, artinya self adalah parent + # if not self.parent_id: + # # Ambil semua child dari parent ini + # children = self.child_ids + # + # # Perbarui vals dengan nilai dari parent jika tidak ada dalam vals + # vals['customer_type'] = vals.get('customer_type', self.customer_type) + # vals['nama_wajib_pajak'] = vals.get('nama_wajib_pajak', self.nama_wajib_pajak) + # vals['npwp'] = vals.get('npwp', self.npwp) + # vals['sppkp'] = vals.get('sppkp', self.sppkp) + # vals['alamat_lengkap_text'] = vals.get('alamat_lengkap_text', self.alamat_lengkap_text) + # vals['industry_id'] = vals.get('industry_id', self.industry_id.id if self.industry_id else None) + # vals['company_type_id'] = vals.get('company_type_id', self.company_type_id.id if self.company_type_id else None) + # + # # Referensi + # vals['supplier_ids'] = vals.get('supplier_ids', self.supplier_ids) + # + # # informasi perusahaan + # vals['name_tempo'] = vals.get('name_tempo', self.name_tempo) + # vals['industry_id_tempo'] = vals.get('industry_id_tempo', self.industry_id_tempo) + # vals['street_tempo'] = vals.get('street_tempo', self.street_tempo) + # vals['state_id_tempo'] = vals.get('state_id_tempo', self.state_id_tempo) + # vals['city_id_tempo'] = vals.get('city_id_tempo', self.city_id_tempo) + # vals['zip_tempo'] = vals.get('zip_tempo', self.zip_tempo) + # vals['bank_name_tempo'] = vals.get('bank_name_tempo', self.bank_name_tempo) + # vals['account_name_tempo'] = vals.get('account_name_tempo', self.account_name_tempo) + # vals['account_number_tempo'] = vals.get('account_number_tempo', self.account_number_tempo) + # vals['website_tempo'] = vals.get('website_tempo', self.website_tempo) + # vals['portal'] = vals.get('portal', self.portal) + # vals['estimasi_tempo'] = vals.get('estimasi_tempo', self.estimasi_tempo) + # vals['tempo_duration'] = vals.get('tempo_duration', self.tempo_duration) + # vals['tempo_limit'] = vals.get('tempo_limit', self.tempo_limit) + # vals['category_produk_ids'] = vals.get('category_produk_ids', self.category_produk_ids) + # + # # Kontak Perusahaan + # vals['direktur_name'] = vals.get('direktur_name', self.direktur_name) + # vals['direktur_mobile'] = vals.get('direktur_mobile', self.direktur_mobile) + # vals['direktur_email'] = vals.get('direktur_email', self.direktur_email) + # vals['purchasing_name'] = vals.get('purchasing_name', self.purchasing_name) + # vals['purchasing_mobile'] = vals.get('purchasing_mobile', self.purchasing_mobile) + # vals['purchasing_email'] = vals.get('purchasing_email', self.purchasing_email) + # vals['finance_name'] = vals.get('finance_name', self.finance_name) + # vals['finance_mobile'] = vals.get('finance_mobile', self.finance_mobile) + # vals['finance_email'] = vals.get('finance_email', self.finance_email) + # + # # Pengiriman + # vals['pic_name'] = vals.get('pic_name', self.pic_name) + # vals['pic_mobile'] = vals.get('pic_mobile', self.pic_mobile) + # vals['street_pengiriman'] = vals.get('street_pengiriman', self.street_pengiriman) + # vals['state_id_pengiriman'] = vals.get('state_id_pengiriman', self.state_id_pengiriman) + # vals['city_id_pengiriman'] = vals.get('city_id_pengiriman', self.city_id_pengiriman) + # vals['district_id_pengiriman'] = vals.get('district_id_pengiriman', self.district_id_pengiriman) + # vals['subDistrict_id_pengiriman'] = vals.get('subDistrict_id_pengiriman', self.subDistrict_id_pengiriman) + # vals['zip_pengiriman'] = vals.get('zip_pengiriman', self.zip_pengiriman) + # vals['invoice_pic'] = vals.get('invoice_pic', self.invoice_pic) + # vals['invoice_pic_mobile'] = vals.get('invoice_pic_mobile', self.invoice_pic_mobile) + # vals['street_invoice'] = vals.get('street_invoice', self.street_invoice) + # vals['state_id_invoice'] = vals.get('state_id_invoice', self.state_id_invoice) + # vals['city_id_invoice'] = vals.get('city_id_invoice', self.city_id_invoice) + # vals['district_id_invoice'] = vals.get('district_id_invoice', self.district_id_invoice) + # vals['subDistrict_id_invoice'] = vals.get('subDistrict_id_invoice', self.subDistrict_id_invoice) + # vals['zip_invoice'] = vals.get('zip_invoice', self.zip_invoice) + # vals['tukar_invoice'] = vals.get('tukar_invoice', self.tukar_invoice) + # vals['jadwal_bayar'] = vals.get('jadwal_bayar', self.jadwal_bayar) + # vals['dokumen_prosedur'] = vals.get('dokumen_prosedur', self.dokumen_prosedur) + # vals['dokumen_pengiriman'] = vals.get('dokumen_pengiriman', self.dokumen_pengiriman) + # vals['dokumen_pengiriman_input'] = vals.get('dokumen_pengiriman_input', self.dokumen_pengiriman_input) + # vals['dokumen_invoice'] = vals.get('dokumen_invoice', self.dokumen_invoice) + # + # # Dokumen + # vals['dokumen_npwp'] = vals.get('dokumen_npwp', self.dokumen_npwp) + # vals['dokumen_sppkp'] = vals.get('dokumen_sppkp', self.dokumen_sppkp) + # vals['dokumen_nib'] = vals.get('dokumen_nib', self.dokumen_nib) + # vals['dokumen_siup'] = vals.get('dokumen_siup', self.dokumen_siup) + # vals['dokumen_tdp'] = vals.get('dokumen_tdp', self.dokumen_tdp) + # vals['dokumen_skdp'] = vals.get('dokumen_skdp', self.dokumen_skdp) + # vals['dokumen_skt'] = vals.get('dokumen_skt', self.dokumen_skt) + # vals['dokumen_akta_perubahan'] = vals.get('dokumen_akta_perubahan', self.dokumen_akta_perubahan) + # vals['dokumen_ktp_dirut'] = vals.get('dokumen_ktp_dirut', self.dokumen_ktp_dirut) + # vals['dokumen_akta_pendirian'] = vals.get('dokumen_akta_pendirian', self.dokumen_akta_pendirian) + # vals['dokumen_laporan_keuangan'] = vals.get('dokumen_laporan_keuangan', self.dokumen_laporan_keuangan) + # vals['dokumen_foto_kantor'] = vals.get('dokumen_foto_kantor', self.dokumen_foto_kantor) + # vals['dokumen_tempat_bekerja'] = vals.get('dokumen_tempat_bekerja', self.dokumen_tempat_bekerja) + # + # # Simpan hanya field yang perlu di-update pada child + # vals_for_child = { + # 'customer_type': vals.get('customer_type'), + # 'nama_wajib_pajak': vals.get('nama_wajib_pajak'), + # 'npwp': vals.get('npwp'), + # 'sppkp': vals.get('sppkp'), + # 'alamat_lengkap_text': vals.get('alamat_lengkap_text'), + # 'industry_id': vals.get('industry_id'), + # 'company_type_id': vals.get('company_type_id'), + # 'supplier_ids': vals.get('supplier_ids'), + # 'name_tempo': vals.get('name_tempo'), + # 'industry_id_tempo': vals.get('industry_id_tempo'), + # 'street_tempo': vals.get('street_tempo'), + # 'state_id_tempo': vals.get('state_id_tempo'), + # 'city_id_tempo': vals.get('city_id_tempo'), + # 'zip_tempo': vals.get('zip_tempo'), + # 'bank_name_tempo': vals.get('bank_name_tempo'), + # 'account_name_tempo': vals.get('account_name_tempo'), + # 'account_number_tempo': vals.get('account_number_tempo'), + # 'website_tempo': vals.get('website_tempo'), + # 'portal': vals.get('portal'), + # 'estimasi_tempo': vals.get('estimasi_tempo'), + # 'tempo_duration': vals.get('tempo_duration'), + # 'tempo_limit': vals.get('tempo_limit'), + # 'category_produk_ids': vals.get('category_produk_ids'), + # 'direktur_name': vals.get('direktur_name'), + # 'direktur_mobile': vals.get('direktur_mobile'), + # 'direktur_email': vals.get('direktur_email'), + # 'purchasing_name': vals.get('purchasing_name'), + # 'purchasing_mobile': vals.get('purchasing_mobile'), + # 'purchasing_email': vals.get('purchasing_email'), + # 'finance_name': vals.get('finance_name'), + # 'finance_mobile': vals.get('finance_mobile'), + # 'finance_email': vals.get('finance_email'), + # 'pic_name': vals.get('pic_name'), + # 'pic_mobile': vals.get('pic_mobile'), + # 'street_pengiriman': vals.get('street_pengiriman'), + # 'state_id_pengiriman': vals.get('state_id_pengiriman'), + # 'city_id_pengiriman': vals.get('city_id_pengiriman'), + # 'district_id_pengiriman': vals.get('district_id_pengiriman'), + # 'subDistrict_id_pengiriman': vals.get('subDistrict_id_pengiriman'), + # 'zip_pengiriman': vals.get('zip_pengiriman'), + # 'invoice_pic': vals.get('invoice_pic'), + # 'invoice_pic_mobile': vals.get('invoice_pic_mobile'), + # 'street_invoice': vals.get('street_invoice'), + # 'state_id_invoice': vals.get('state_id_invoice'), + # 'city_id_invoice': vals.get('city_id_invoice'), + # 'district_id_invoice': vals.get('district_id_invoice'), + # 'subDistrict_id_invoice': vals.get('subDistrict_id_invoice'), + # 'zip_invoice': vals.get('zip_invoice'), + # 'tukar_invoice': vals.get('tukar_invoice'), + # 'jadwal_bayar': vals.get('jadwal_bayar'), + # 'dokumen_prosedur': vals.get('dokumen_prosedur'), + # 'dokumen_pengiriman': vals.get('dokumen_pengiriman'), + # 'dokumen_pengiriman_input': vals.get('dokumen_pengiriman_input'), + # 'dokumen_invoice': vals.get('dokumen_invoice'), + # 'dokumen_npwp': vals.get('dokumen_npwp'), + # 'dokumen_sppkp': vals.get('dokumen_sppkp'), + # 'dokumen_nib': vals.get('dokumen_nib'), + # 'dokumen_siup': vals.get('dokumen_siup'), + # 'dokumen_tdp': vals.get('dokumen_tdp'), + # 'dokumen_skdp': vals.get('dokumen_skdp'), + # 'dokumen_skt': vals.get('dokumen_skt'), + # 'dokumen_akta_perubahan': vals.get('dokumen_akta_perubahan'), + # 'dokumen_ktp_dirut': vals.get('dokumen_ktp_dirut'), + # 'dokumen_akta_pendirian': vals.get('dokumen_akta_pendirian'), + # 'dokumen_laporan_keuangan': vals.get('dokumen_laporan_keuangan'), + # 'dokumen_foto_kantor': vals.get('dokumen_foto_kantor'), + # 'dokumen_tempat_bekerja': vals.get('dokumen_tempat_bekerja'), + # + # # internal_notes + # 'comment': vals.get('comment') + # } + # + # # Lakukan update pada semua child secara rekursif + # for child in children: + # update_children_recursively(child, vals_for_child) + # + # # Lakukan write untuk parent dengan vals asli + # res = super(ResPartner, self).write(vals) + # + # return res # if self.company_type == 'person' and not partner.parent_id: # if self.parent_id: diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index f89dfb10..fa570819 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1259,6 +1259,7 @@ class SaleOrder(models.Model): self._validate_order() for order in self: + order._validate_delivery_amt() order._validate_uniform_taxes() order.order_line.validate_line() order.check_data_real_delivery_address() @@ -1501,6 +1502,7 @@ class SaleOrder(models.Model): def action_confirm(self): for order in self: + order._validate_delivery_amt() order._validate_uniform_taxes() order.check_duplicate_product() order.check_product_bom() @@ -1962,7 +1964,7 @@ class SaleOrder(models.Model): order = super(SaleOrder, self).create(vals) order._compute_etrts_date() order._validate_expected_ready_ship_date() - order._validate_delivery_amt() + # order._validate_delivery_amt() # order._check_total_margin_excl_third_party() # order._update_partner_details() return order diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 9247d1c1..c8066961 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -6,19 +6,22 @@ from datetime import datetime, timedelta class SaleOrderLine(models.Model): _inherit = 'sale.order.line' item_margin = fields.Float('Margin', compute='compute_item_margin', help="Total Margin in Sales Order Header") - item_before_margin = fields.Float('Before Margin', compute='compute_item_before_margin', help="Total Margin in Sales Order Header") - item_percent_margin = fields.Float('%Margin', compute='compute_item_margin', help="Total % Margin in Sales Order Header") + item_before_margin = fields.Float('Before Margin', compute='compute_item_before_margin', + help="Total Margin in Sales Order Header") + item_percent_margin = fields.Float('%Margin', compute='compute_item_margin', + help="Total % Margin in Sales Order Header") initial_discount = fields.Float('Initial Discount') vendor_id = fields.Many2one( 'res.partner', string='Vendor', readonly=True, change_default=True, index=True, tracking=1, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]" - ) - vendor_md_id = fields.Many2one('res.partner', string='MD Vendor') + ) + vendor_md_id = fields.Many2one('res.partner', string='MD Vendor') purchase_price = fields.Float('Purchase', required=True, digits='Product Price', default=0.0) purchase_price_md = fields.Float('MD Purchase') - purchase_tax_id = fields.Many2one('account.tax', string='Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) + purchase_tax_id = fields.Many2one('account.tax', string='Tax', + domain=['|', ('active', '=', False), ('active', '=', True)]) delivery_amt_line = fields.Float('DeliveryAmtLine', compute='compute_delivery_amt_line') fee_third_party_line = fields.Float('FeeThirdPartyLine', compute='compute_fee_third_party_line', default=0) line_no = fields.Integer('No', default=0, copy=False) @@ -28,13 +31,15 @@ class SaleOrderLine(models.Model): ('info_vendor', 'Info Vendor'), ('penggabungan', 'Penggabungan'), ], string='Note', help="Harap diisi jika ada keterangan tambahan dari Procurement, agar dapat dimonitoring") - note_procurement = fields.Char(string='Note Detail', help="Harap diisi jika ada keterangan tambahan dari Procurement, agar dapat dimonitoring") + note_procurement = fields.Char(string='Note Detail', + help="Harap diisi jika ada keterangan tambahan dari Procurement, agar dapat dimonitoring") vendor_subtotal = fields.Float(string='Vendor Subtotal', compute="_compute_vendor_subtotal") amount_voucher_disc = fields.Float(string='Voucher Discount') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') - product_available_quantity = fields.Float(string='Qty pickup by user',) + product_available_quantity = fields.Float(string='Qty pickup by user', ) reserved_from = fields.Char(string='Reserved From', copy=False) - item_percent_margin_without_deduction = fields.Float('Margin Without Deduction', compute='_compute_item_margin_without_deduction') + item_percent_margin_without_deduction = fields.Float('Margin Without Deduction', + compute='_compute_item_margin_without_deduction') weight = fields.Float(string='Weight') md_vendor_id = fields.Many2one('res.partner', string='MD Vendor', readonly=True) margin_md = fields.Float(string='Margin MD') @@ -45,7 +50,8 @@ class SaleOrderLine(models.Model): outgoing_moves = self.env['stock.move'] incoming_moves = self.env['stock.move'] - for move in self.move_ids.filtered(lambda r: r.state != 'cancel' and not r.scrapped and self.product_id == r.product_id): + for move in self.move_ids.filtered( + lambda r: r.state != 'cancel' and not r.scrapped and self.product_id == r.product_id): if move.location_dest_id.usage == "customer": if not move.origin_returned_move_id or (move.origin_returned_move_id and move.to_refund): outgoing_moves |= move @@ -80,7 +86,7 @@ class SaleOrderLine(models.Model): if not self.product_uom or not self.product_id: self.price_unit = 0.0 return - + self.price_unit = self.price_unit def _compute_qty_reserved(self): @@ -158,7 +164,7 @@ class SaleOrderLine(models.Model): line.item_percent_margin = 0 if not line.margin_md: - line.margin_md = line.item_percent_margin + line.margin_md = line.item_percent_margin def compute_item_before_margin(self): for line in self: @@ -169,7 +175,7 @@ class SaleOrderLine(models.Model): continue # calculate margin without tax sales_price = line.price_reduce_taxexcl * line.product_uom_qty - + purchase_price = line.purchase_price if line.purchase_tax_id.price_include: purchase_price = line.purchase_price / 1.11 @@ -183,7 +189,7 @@ class SaleOrderLine(models.Model): # TODO : need to change this logic @stephan if not self.product_id or self.product_id.type == 'service': return - elif self.product_id.categ_id.id == 34: # finish good / manufacturing only + elif self.product_id.categ_id.id == 34: # finish good / manufacturing only cost = self.product_id.standard_price self.purchase_price = cost elif self.product_id.x_manufacture.override_vendor_id: @@ -195,12 +201,12 @@ class SaleOrderLine(models.Model): self.purchase_price = price self.purchase_tax_id = taxes # else: - # purchase_price = self.env['purchase.pricelist'].search( - # [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', self.product_id.id)], - # limit=1, order='count_trx_po desc, count_trx_po_vendor desc') - # price, taxes = self._get_valid_purchase_price(purchase_price) - # self.purchase_price = price - # self.purchase_tax_id = taxes + # purchase_price = self.env['purchase.pricelist'].search( + # [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', self.product_id.id)], + # limit=1, order='count_trx_po desc, count_trx_po_vendor desc') + # price, taxes = self._get_valid_purchase_price(purchase_price) + # self.purchase_price = price + # self.purchase_tax_id = taxes # def _calculate_selling_price(self): # rec_purchase_price, rec_taxes, rec_vendor_id = self._get_purchase_price(self.product_id) @@ -260,7 +266,7 @@ class SaleOrderLine(models.Model): price = 0 taxes = 24 - vendor_id = '' + vendor_id = False human_last_update = purchase_price.human_last_update or datetime.min system_last_update = purchase_price.system_last_update or datetime.min @@ -271,18 +277,18 @@ class SaleOrderLine(models.Model): if delta_time > human_last_update: price = 0 taxes = 24 - vendor_id = '' + vendor_id = False if system_last_update > human_last_update: - #if purchase_price.taxes_system_id.type_tax_use == 'purchase': + # if purchase_price.taxes_system_id.type_tax_use == 'purchase': price = purchase_price.system_price taxes = purchase_price.taxes_system_id.id or 24 vendor_id = purchase_price.vendor_id.id if delta_time > system_last_update: price = 0 taxes = 24 - vendor_id = '' - + vendor_id = False + return price, taxes, vendor_id @api.onchange('product_id') @@ -302,11 +308,11 @@ class SaleOrderLine(models.Model): line.tax_id = line.order_id.sales_tax_id # price, taxes = line._get_valid_purchase_price(purchase_price) line.purchase_price = price - line.purchase_tax_id = taxes + line.purchase_tax_id = taxes attribute_values = line.product_id.product_template_attribute_value_ids.mapped('name') attribute_values_str = ', '.join(attribute_values) if attribute_values else '' - + line_name = ('[' + line.product_id.default_code + ']' if line.product_id.default_code else '') + ' ' + \ (line.product_id.name if line.product_id.name else '') + ' ' + \ ('(' + attribute_values_str + ')' if attribute_values_str else '') + ' ' + \ @@ -324,7 +330,7 @@ class SaleOrderLine(models.Model): price, taxes, vendor_id = self._get_purchase_price(line.product_id) line.vendor_md_id = vendor_id if vendor_id else None line.margin_md = line.item_percent_margin - line.purchase_price_md = price + line.purchase_price_md = price def compute_delivery_amt_line(self): for line in self: @@ -363,11 +369,15 @@ class SaleOrderLine(models.Model): fiscal_position=self.env.context.get('fiscal_position') ) - product_context = dict(self.env.context, partner_id=self.order_id.partner_id.id, date=self.order_id.date_order, uom=self.product_uom.id) + product_context = dict(self.env.context, partner_id=self.order_id.partner_id.id, date=self.order_id.date_order, + uom=self.product_uom.id) price, rule_id = self.order_id.pricelist_id.with_context(product_context).get_product_price_rule( self.product_id, self.product_uom_qty or 1.0, self.order_id.partner_id) - new_list_price, currency = self.with_context(product_context)._get_real_price_currency(product, rule_id, self.product_uom_qty, self.product_uom, self.order_id.pricelist_id.id) + new_list_price, currency = self.with_context(product_context)._get_real_price_currency(product, rule_id, + self.product_uom_qty, + self.product_uom, + self.order_id.pricelist_id.id) new_list_price = product.web_price if new_list_price != 0: @@ -390,8 +400,8 @@ class SaleOrderLine(models.Model): no_variant_attributes_price_extra = [ ptav.price_extra for ptav in self.product_no_variant_attribute_value_ids.filtered( lambda ptav: - ptav.price_extra and - ptav not in product.product_template_attribute_value_ids + ptav.price_extra and + ptav not in product.product_template_attribute_value_ids ) ] if no_variant_attributes_price_extra: @@ -401,10 +411,15 @@ class SaleOrderLine(models.Model): if self.order_id.pricelist_id.discount_policy == 'with_discount': return product.with_context(pricelist=self.order_id.pricelist_id.id, uom=self.product_uom.id).price - product_context = dict(self.env.context, partner_id=self.order_id.partner_id.id, date=self.order_id.date_order, uom=self.product_uom.id) - - final_price, rule_id = self.order_id.pricelist_id.with_context(product_context).get_product_price_rule(product or self.product_id, self.product_uom_qty or 1.0, self.order_id.partner_id) - base_price, currency = self.with_context(product_context)._get_real_price_currency(product, rule_id, self.product_uom_qty, self.product_uom, self.order_id.pricelist_id.id) + product_context = dict(self.env.context, partner_id=self.order_id.partner_id.id, date=self.order_id.date_order, + uom=self.product_uom.id) + + final_price, rule_id = self.order_id.pricelist_id.with_context(product_context).get_product_price_rule( + product or self.product_id, self.product_uom_qty or 1.0, self.order_id.partner_id) + base_price, currency = self.with_context(product_context)._get_real_price_currency(product, rule_id, + self.product_uom_qty, + self.product_uom, + self.order_id.pricelist_id.id) base_price = product.web_price if currency != self.order_id.pricelist_id.currency_id: base_price = currency._convert( @@ -413,7 +428,7 @@ class SaleOrderLine(models.Model): # negative discounts (= surcharge) are included in the display price return max(base_price, final_price) - + def validate_line(self): for line in self: if line.product_id.id in [385544, 224484, 417724]: diff --git a/indoteknik_custom/models/shipment_group.py b/indoteknik_custom/models/shipment_group.py index 87d222a6..fcde39c9 100644 --- a/indoteknik_custom/models/shipment_group.py +++ b/indoteknik_custom/models/shipment_group.py @@ -19,11 +19,13 @@ class ShipmentGroup(models.Model): def sync_api_shipping(self): for rec in self.shipment_line: - if rec.shipment_id.carrier_id == 173: - rec.picking_id.action_get_kgx_pod() - - if rec.shipment_id.carrier_id == 151: - rec.picking_id.track_envio_shipment() + picking_names = [lines.picking_id.name for lines in self.shipment_line] + if rec.shipment_id.carrier_id.id == 173: + rec.picking_id.action_get_kgx_pod( + shipment=f"{self.number}, {', '.join(picking_names)}" + ) + elif rec.shipment_id.carrier_id.id == 151: + rec.picking_id.track_envio_shipment(shipment=f"{self.number}") @api.depends('shipment_line.total_colly') def _compute_total_colly_line(self): diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 0fcb7ca1..a215eb74 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -310,10 +310,10 @@ class StockPicking(models.Model): except ValueError: return False - def action_get_kgx_pod(self): + def action_get_kgx_pod(self, shipment=False): self.ensure_one() - awb_number = self._get_kgx_awb_number() + awb_number = shipment or self._get_kgx_awb_number() if not awb_number: raise UserError("Nomor AWB tidak dapat dibuat, pastikan picking memiliki name dan origin") @@ -619,18 +619,19 @@ class StockPicking(models.Model): except ValueError: raise UserError(f"Format waktu tidak sesuai: {date_str}") - def track_envio_shipment(self): + def track_envio_shipment(self, shipment=False): pickings = self.env['stock.picking'].search([ ('picking_type_code', '=', 'outgoing'), ('state', '=', 'done'), ('carrier_id', '=', 151) ]) - for picking in pickings: + for picking in self: + name = shipment or picking.name if not picking.name: raise UserError("Name pada stock.picking tidak ditemukan.") # API URL dan headers - url = f"https://api.envio.co.id/v1/tracking/distribution?code={picking.name}" + url = f"https://api.envio.co.id/v1/tracking/distribution?code={name}" headers = { 'Authorization': 'Bearer JZ0Seh6qpYJAC3CJHdhF7sPqv8B/uSSfZe1VX5BL?vPYdo', 'Content-Type': 'application/json', @@ -1269,6 +1270,20 @@ class StockPicking(models.Model): current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.date_reserved = current_time + # Validate Qty Demand Can't higher than Qty Product + for move_line in self.move_line_ids_without_package: + purchase_line = move_line.move_id.purchase_line_id + if purchase_line: + if purchase_line.product_uom_qty < move_line.product_uom_qty: + raise UserError( + _("Quantity demand (%s) tidak bisa lebih besar dari qty product (%s) untuk produk %s") % ( + move_line.product_uom_qty, + purchase_line.product_uom_qty, + move_line.product_id.display_name + ) + ) + + self.validation_minus_onhand_quantity() self.responsible = self.env.user.id # self.send_koli_to_so() |
