diff options
| author | Indoteknik . <it@fixcomart.co.id> | 2025-08-01 17:00:42 +0700 |
|---|---|---|
| committer | Indoteknik . <it@fixcomart.co.id> | 2025-08-01 17:00:42 +0700 |
| commit | 71c0324d483419d3b91078cf6efc2263f279362a (patch) | |
| tree | 018daebf755b52449ca1323a337673fa61d8087e /indoteknik_api | |
| parent | a6da6185d08075fe6819427e22fdb1940d50fe62 (diff) | |
| parent | c8ef030b4c1cb6b8daa14c081f569c71fbbda639 (diff) | |
Merge branch 'odoo-backup' of https://bitbucket.org/altafixco/indoteknik-addons into odoo-backup
Diffstat (limited to 'indoteknik_api')
| -rw-r--r-- | indoteknik_api/controllers/api_v1/sale_order.py | 106 | ||||
| -rw-r--r-- | indoteknik_api/models/sale_order.py | 65 |
2 files changed, 141 insertions, 30 deletions
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index ccab2827..fd460ea0 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -1,5 +1,5 @@ from .. import controller -from odoo import http +from odoo import http, fields from datetime import datetime, timedelta from odoo.http import request import json @@ -103,7 +103,11 @@ class SaleOrder(controller.Controller): 'site': [], 'limit': ['default:0', 'number'], 'offset': ['default:0', 'number'], - 'context': [] + 'context': [], + 'status': [], + 'sort': [], + 'startDate': [], + 'endDate': [], }) limit = params['value']['limit'] offset = params['value']['offset'] @@ -123,10 +127,19 @@ class SaleOrder(controller.Controller): if params['value']['name']: name = params['value']['name'].replace(' ', '%') - domain += [ + order_lines = request.env['sale.order.line'].search([ + ('order_id.partner_id', 'in', partner_child_ids), '|', - ('name', 'ilike', '%' + name + '%'), - ('partner_purchase_order_name', 'ilike', '%' + name + '%') + ('product_id.name', 'ilike', name), + ('product_id.default_code', 'ilike', name), + ]) + + sale_order_ids_from_lines = order_lines.mapped('order_id.id') + + domain += ['|', '|', + ('name', 'ilike', name), + ('partner_purchase_order_name', 'ilike', name), + ('id', 'in', sale_order_ids_from_lines) ] if params['value']['site']: @@ -135,11 +148,86 @@ class SaleOrder(controller.Controller): ('partner_id.site_id.name', 'ilike', '%' + site + '%') ] + status = params['value'].get('status') + if status: + if status == 'quotation': + domain += [('state', '=', 'draft')] + domain += [('approval_status', '=', False)] + + elif status == 'cancel': + domain += [('state', '=', 'cancel')] + + elif status == 'diproses': + domain += [ + ('state', '=', 'draft'), + ('approval_status', 'in', ['pengajuan1', 'pengajuan2']), + ] + + elif status in ['dikemas', 'dikirim', 'selesai', 'partial']: + domain += [('state', '=', 'sale')] + + elif status == 'all': + domain += [] + + # Sorting + order = None + if params['value']['sort']: + if params['value']['sort'] == 'asc': + order = 'amount_total asc' + elif params['value']['sort'] == 'desc': + order = 'amount_total desc' + + # Filter berdasarkan tanggal order + try: + if params['value']['startDate'] and params['value']['endDate']: + start_date = datetime.strptime(params['value']['startDate'], '%d/%m/%Y').strftime('%Y-%m-%d 00:00:00') + end_date = datetime.strptime(params['value']['endDate'], '%d/%m/%Y').strftime('%Y-%m-%d 23:59:59') + else: + start_date = '2023-01-01 00:00:00' + end_date = fields.Datetime.now().strftime('%Y-%m-%d 23:59:59') + + domain.append(('date_order', '>=', start_date)) + domain.append(('date_order', '<=', end_date)) + + except ValueError: + return self.response(code=400, description="Invalid date format. Use 'DD/MM/YYYY'.") + + + sale_orders = request.env['sale.order'].search( - domain, offset=offset, limit=limit) + domain, order=order) + status = params['value'].get('status') + if status in ['dikemas', 'dikirim', 'selesai', 'partial']: + filtered_orders = [] + for sale_order in sale_orders: + bu_pickings = [ + p for p in sale_order.picking_ids + if p.picking_type_id and p.picking_type_id.id == 29 + ] + 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.driver_arrival_date] + done_without_driver = [p for p in done_pickings if not p.driver_arrival_date] + + if status == 'dikemas' and len(done_pickings) == 0: + filtered_orders.append(sale_order) + elif status == 'dikirim' and len(done_pickings) == total and len(done_pickings) > 0 and len(done_without_driver) == total: + filtered_orders.append(sale_order) + elif status == 'selesai' and len(done_pickings) == total and len(done_pickings) > 0 and len(done_with_driver) == total: + filtered_orders.append(sale_order) + elif status == 'partial' and ( + len(done_pickings) != total or + (done_with_driver and done_without_driver) + ): + filtered_orders.append(sale_order) + else: + filtered_orders = sale_orders + + filtered_orders_paginated = filtered_orders[offset: offset + limit] + data = { - 'sale_order_total': request.env['sale.order'].search_count(domain), - 'sale_orders': [request.env['sale.order'].api_v1_single_response(x) for x in sale_orders] + 'sale_order_total': len(filtered_orders), + 'sale_orders': [request.env['sale.order'].api_v1_single_response(x) for x in filtered_orders_paginated] } return self.response(data) @@ -149,7 +237,7 @@ class SaleOrder(controller.Controller): def partner_get_sale_order_detail(self, **kw): params = self.get_request_params(kw, { 'partner_id': ['number'], - 'id': ['number'] + 'id': ['number'], }) if not params['valid']: return self.response(code=400, description=params) diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 45461974..615dcdcb 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -1,4 +1,5 @@ from odoo import models +from datetime import datetime class SaleOrder(models.Model): @@ -20,12 +21,14 @@ class SaleOrder(models.Model): '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, 'pickings': [] } for picking in sale_order.picking_ids: @@ -49,29 +52,32 @@ class SaleOrder(models.Model): }) if sale_order.state == 'cancel': data['status'] = 'cancel' - if sale_order.state in ['draft', 'sent']: + if sale_order.state == 'draft' and sale_order.approval_status == False: data['status'] = 'draft' - if sale_order.is_continue_transaction: - data['status'] = 'waiting' - if sale_order.approval_status in ['pengajuan1', 'pengajuan2']: - data['status'] = 'waiting' - if sale_order.state == 'sale': - data['status'] = 'sale' - picking_count = { - 'assigned': 0, - 'done': 0, - } - for picking in sale_order.picking_ids: - if picking.state in ['confirmed', 'assigned']: - picking_count['assigned'] += 1 - if picking.state == 'done': - picking_count['done'] += 1 - if picking_count['done'] > 0: + if sale_order.state == 'draft' and sale_order.approval_status in ['pengajuan1', 'pengajuan2']: + 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 + ] + + # 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.driver_arrival_date] + done_without_driver = [p for p in done_pickings if not p.driver_arrival_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' - if picking_count['assigned'] > 0: - data['status'] = 'partial_shipping' - if sale_order.state == 'done': - data['status'] = 'done' + else: + data['status'] = 'partial_shipping' res_users = self.env['res.users'] if context: @@ -116,11 +122,28 @@ class SaleOrder(models.Model): 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 |
