from odoo import models from datetime import datetime class SaleOrder(models.Model): _inherit = 'sale.order' def api_v1_single_response(self, sale_order, context=False): APPROVAL_STEP = { 'company': 1, 'cust_manager': 2, 'cust_director': 3 } data = { 'token': self.env['rest.api'].md5_salt(sale_order.id, 'sale.order'), 'id': sale_order.id, 'name': sale_order.name, 'site_partner': sale_order.partner_id.site_id.name, 'sales': sale_order.user_id.name, 'amount_untaxed': sale_order.amount_untaxed, 'amount_tax': sale_order.amount_tax, 'amount_total': sale_order.grand_total, 'amount_discount': sale_order.amount_voucher_shipping_disc, 'purchase_order_name': sale_order.partner_purchase_order_name or sale_order.client_order_ref, 'purchase_order_file': True if sale_order.partner_purchase_order_file else False, 'invoice_count': sale_order.invoice_count, 'status': 'draft', 'approval_step': APPROVAL_STEP[sale_order.web_approval] if sale_order.web_approval else 0, 'date_order': self.env['rest.api'].datetime_to_str(sale_order.date_order, '%d/%m/%Y %H:%M:%S'), 'payment_type': sale_order.payment_type, 'carrier_id': sale_order.carrier_id.id, 'carrier_name': sale_order.carrier_id.name, 'service_type': sale_order.shipping_option_id.name, 'pickings': [] } for picking in sale_order.picking_ids: picking_model = self.env['stock.picking'].sudo().search([('id', '=', picking.id), ('name', 'like', '%BU/OUT/%')], limit=1) if not picking_model: continue response = picking_model.get_tracking_detail() data['pickings'].append({ 'waybill_number' : response['waybill_number'] or '', 'delivered_date': response['delivered_date'], 'delivery_order' : { 'carrier' : response['delivery_order']['carrier'] or '', 'service' : response['delivery_order']['service'] or '' }, 'eta' : response['eta'], 'id': picking.id, 'name': picking.name, 'products': [{ 'id': product.id, 'name': product.name, 'image': self.env['ir.attachment'].api_image('product.template', 'image_128', product.product_tmpl_id.id), 'code': product.default_code or '' } for product in picking.move_line_ids.product_id], 'product_count': len(picking.move_line_ids) # 'tracking_number': picking.delivery_tracking_no or '', # 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False or picking.sj_return_date != False, }) if sale_order.state == 'cancel': data['status'] = 'cancel' elif sale_order.state == 'draft': if not sale_order.approval_status: data['status'] = 'draft' elif sale_order.approval_status in ('pengajuan0', 'pengajuan1', 'pengajuan2'): if sale_order.payment_status in ('', 'pending', False, None, 'expire'): data['status'] = 'belum_bayar' elif sale_order.payment_status not in ['', 'pending', False, None, 'expire']: data['status'] = 'waiting' if sale_order.state == 'sale': bu_pickings = [ p for p in sale_order.picking_ids if p.picking_type_id and p.picking_type_id.id == 29 and p.state != 'cancel' ] # Hitung status masing-masing picking total = len(bu_pickings) done_pickings = [p for p in bu_pickings if p.state == 'done'] done_with_driver = [p for p in done_pickings if p.sj_return_date] done_without_driver = [p for p in done_pickings if not p.sj_return_date] if len(done_pickings) == 0: data['status'] = 'sale' elif len(done_pickings) == total and len(done_pickings) > 0 and len(done_with_driver) == total: data['status'] = 'done' elif len(done_pickings) == total and len(done_pickings) > 0 and len(done_without_driver) == total: data['status'] = 'shipping' else: data['status'] = 'partial_shipping' res_users = self.env['res.users'] if context: if context == 'with_detail': data_with_detail = { 'payment_term': sale_order.payment_term_id.name or '', 'products': [], 'products_reject_line': [], 'delivery_amount': sale_order.delivery_amt or 0, 'address': { 'site_partner': sale_order.partner_id.site_id.name, 'customer': res_users.api_address_response(sale_order.partner_id), 'invoice': res_users.api_address_response(sale_order.partner_invoice_id), 'shipping': res_users.api_address_response(sale_order.partner_shipping_id) }, 'invoices': [] } for line in sale_order.order_line: product = self.env['product.product'].api_single_response(line.product_id) product['price'] = { 'price': line.price_unit, 'discount_percentage': line.discount, 'price_discount': line.price_reduce_taxexcl, 'subtotal': line.price_subtotal } product['quantity'] = line.product_uom_qty product['available_quantity'] = line.product_available_quantity for data_v2 in sale_order.fulfillment_line_v2: product_v2 = self.env['product.product'].api_single_response(data_v2.product_id) if product['id'] == product_v2['id']: product['so_qty'] = data_v2.so_qty product['reserved_stock_qty'] = data_v2.reserved_stock_qty data_with_detail['products'].append(product) for invoice in sale_order.invoice_ids: if invoice.state == 'posted': data_with_detail['invoices'].append(self.env['account.move'].api_v1_single_response(invoice)) for reject in sale_order.reject_line: if len(reject) > 0: product_reject = self.env['product.product'].api_single_response(reject.product_id) product_reject['quantity'] = reject.qty_reject data_with_detail['products_reject_line'].append(product_reject) data.update(data_with_detail) else: data_with_detail = { 'products': [], 'address': { 'customer': res_users.api_address_response(sale_order.partner_id), } } data.update(data_with_detail) for line in sale_order.order_line: product = self.env['product.product'].api_single_response(line.product_id) product['price'] = { 'price': line.price_unit, 'discount_percentage': line.discount, 'price_discount': line.price_reduce_taxexcl, 'subtotal': line.price_subtotal } product['quantity'] = line.product_uom_qty product['available_quantity'] = line.product_available_quantity for data_v2 in sale_order.fulfillment_line_v2: product_v2 = self.env['product.product'].api_single_response(data_v2.product_id) if product['id'] == product_v2['id']: product['so_qty'] = data_v2.so_qty product['reserved_stock_qty'] = data_v2.reserved_stock_qty data_with_detail['products'].append(product) return data class SaleOrderLine(models.Model): _inherit = 'sale.order.line' def api_single_response(self, sale_order_line, context=False): data = { 'image': self.env['ir.attachment'].api_image('product.template', 'image_128', sale_order_line.product_id.product_tmpl_id.id), 'item_code': sale_order_line.product_id.default_code, 'product_name': sale_order_line.product_id.name, 'price_before_discount': sale_order_line.price_unit * sale_order_line.product_uom_qty, 'price_after_discount': sale_order_line.price_total, 'tax': sale_order_line.price_tax } return data