From 8cb3d124ec96b78872ebd0d0c969564249f15671 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Fri, 3 Feb 2023 10:39:38 +0700 Subject: [FIX] feature download invoice --- indoteknik_api/controllers/api_v1/download.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'indoteknik_api') diff --git a/indoteknik_api/controllers/api_v1/download.py b/indoteknik_api/controllers/api_v1/download.py index 36f775b5..38225b85 100644 --- a/indoteknik_api/controllers/api_v1/download.py +++ b/indoteknik_api/controllers/api_v1/download.py @@ -16,9 +16,10 @@ class Download(controller.Controller): return result if len(result) > 0 else None @http.route(PREFIX + 'download/invoice/', auth='none', method=['GET']) - def download_invoice(self, **kw): - id = int(kw.get('id', 0)) - return request.render('account.report_invoice', {'id': id}) + def download_invoice(self, id): + id = int(id) + data = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'account.report_invoice')])._render_qweb_pdf([id]) + return request.make_response(base64.b64decode(data[0]), [('Content-Type', 'application/pdf')]) @http.route(PREFIX + 'download/tax-invoice//', auth='none', method=['GET']) def download_tax_invoice(self, id, token): @@ -28,6 +29,7 @@ class Download(controller.Controller): if md5_by_id == token: attachment = self._get_attachment('account.move', 'efaktur_document', id) if attachment: + attachment = attachment[0] return request.make_response(base64.b64decode(attachment['datas']), [('Content-Type', attachment['mimetype'])]) return self.response('Dokumen tidak ditemukan', code=404) -- cgit v1.2.3 From 6b5f3041727d84db4d24215062940b8f2fca6d1c Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Fri, 3 Feb 2023 14:43:58 +0700 Subject: [FIX] feature download invoice --- indoteknik_api/controllers/api_v1/download.py | 28 ++++++++++++++++----------- indoteknik_api/models/account_move.py | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'indoteknik_api') diff --git a/indoteknik_api/controllers/api_v1/download.py b/indoteknik_api/controllers/api_v1/download.py index 38225b85..3794744e 100644 --- a/indoteknik_api/controllers/api_v1/download.py +++ b/indoteknik_api/controllers/api_v1/download.py @@ -15,22 +15,28 @@ class Download(controller.Controller): ], ['datas', 'mimetype']) return result if len(result) > 0 else None - @http.route(PREFIX + 'download/invoice/', auth='none', method=['GET']) - def download_invoice(self, id): + @http.route(PREFIX + 'download/invoice//', auth='none', method=['GET']) + def download_invoice(self, id, token): id = int(id) - data = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'account.report_invoice')])._render_qweb_pdf([id]) - return request.make_response(base64.b64decode(data[0]), [('Content-Type', 'application/pdf')]) + + md5_by_id = request.env['rest.api'].md5_salt(id, 'account.move') + if not md5_by_id == token: + return self.response('Unauthorized') + + pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'account.report_invoice')])._render_qweb_pdf([id]) + return request.make_response(pdf, [('Content-Type', 'application/pdf')]) @http.route(PREFIX + 'download/tax-invoice//', auth='none', method=['GET']) def download_tax_invoice(self, id, token): id = int(id) md5_by_id = request.env['rest.api'].md5_salt(id, 'account.move') - if md5_by_id == token: - attachment = self._get_attachment('account.move', 'efaktur_document', id) - if attachment: - attachment = attachment[0] - return request.make_response(base64.b64decode(attachment['datas']), [('Content-Type', attachment['mimetype'])]) - return self.response('Dokumen tidak ditemukan', code=404) + if not md5_by_id == token: + return self.response('Unauthorized') + + attachment = self._get_attachment('account.move', 'efaktur_document', id) + if attachment: + attachment = attachment[0] + return request.make_response(base64.b64decode(attachment['datas']), [('Content-Type', attachment['mimetype'])]) + return self.response('Dokumen tidak ditemukan', code=404) - return self.response('Tidak diizinkan') diff --git a/indoteknik_api/models/account_move.py b/indoteknik_api/models/account_move.py index f77ded16..3c8fd655 100644 --- a/indoteknik_api/models/account_move.py +++ b/indoteknik_api/models/account_move.py @@ -8,6 +8,7 @@ class AccountMove(models.Model): def api_v1_single_response(self, account_move, context=False): data = { + 'token': self.env['rest.api'].md5_salt(account_move.id, 'account.move'), 'id': account_move.id, 'name': account_move.name, 'purchase_order_name': account_move.ref or '', @@ -16,7 +17,7 @@ class AccountMove(models.Model): 'amount_total': account_move.amount_total, 'amount_residual': account_move.amount_residual, 'invoice_date': '', - 'efaktur_token': self.env['rest.api'].md5_salt(account_move.id, 'account.move') if account_move.efaktur_document else '', + 'efaktur': True if account_move.efaktur_document else False, } if isinstance(object, datetime.date): data['invoice_date'] = account_move.invoice_date.strftime('%d/%m/%Y') -- cgit v1.2.3 From 446e3be759d72b7a06b4e4671b91c6f9c8bfa903 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 6 Feb 2023 12:02:42 +0700 Subject: add api cancel SO and upload PO in SO --- indoteknik_api/controllers/api_v1/download.py | 8 ++-- indoteknik_api/controllers/api_v1/sale_order.py | 56 +++++++++++++++++++++++++ indoteknik_api/models/account_move.py | 1 - indoteknik_api/models/rest_api.py | 5 ++- indoteknik_api/models/sale_order.py | 1 + 5 files changed, 65 insertions(+), 6 deletions(-) (limited to 'indoteknik_api') diff --git a/indoteknik_api/controllers/api_v1/download.py b/indoteknik_api/controllers/api_v1/download.py index 3794744e..f12be337 100644 --- a/indoteknik_api/controllers/api_v1/download.py +++ b/indoteknik_api/controllers/api_v1/download.py @@ -19,8 +19,8 @@ class Download(controller.Controller): def download_invoice(self, id, token): id = int(id) - md5_by_id = request.env['rest.api'].md5_salt(id, 'account.move') - if not md5_by_id == token: + md5_valid = request.env['rest.api'].md5_salt_valid(id, 'account.move', token) + if not md5_valid: return self.response('Unauthorized') pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'account.report_invoice')])._render_qweb_pdf([id]) @@ -30,8 +30,8 @@ class Download(controller.Controller): def download_tax_invoice(self, id, token): id = int(id) - md5_by_id = request.env['rest.api'].md5_salt(id, 'account.move') - if not md5_by_id == token: + md5_valid = request.env['rest.api'].md5_salt_valid(id, 'account.move', token) + if not md5_valid: return self.response('Unauthorized') attachment = self._get_attachment('account.move', 'efaktur_document', id) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 52ccf9fa..9a4b23d9 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -105,6 +105,62 @@ class SaleOrder(controller.Controller): return self.response(data) + @http.route(PREFIX_PARTNER + 'sale_order//upload_po', auth='public', method=['POST', 'OPTIONS'], csrf=False) + def partner_upload_po_sale_order(self, **kw): + user_token = self.authenticate() + if not user_token: + return self.unauthorized_response() + + params = self.get_request_params(kw, { + 'partner_id': ['number'], + 'id': ['number'], + 'name': [], + 'file': [] + }) + if not user_token['partner_id'] == params['value']['partner_id']: + return self.unauthorized_response() + if not params['valid']: + return self.response(code=400, description=params) + partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + domain = [ + ('id', '=', params['value']['id']), + ('partner_id', 'in', partner_child_ids) + ] + data = False + sale_order = request.env['sale.order'].search(domain) + if sale_order: + sale_order.partner_purchase_order_name = params['value']['name'] + sale_order.partner_purchase_order_file = params['value']['file'] + data = sale_order.id + return self.response(data) + + @http.route(PREFIX_PARTNER + 'sale_order//cancel', auth='public', method=['POST', 'OPTIONS'], csrf=False) + def partner_cancel_sale_order(self, **kw): + user_token = self.authenticate() + if not user_token: + return self.unauthorized_response() + + params = self.get_request_params(kw, { + 'partner_id': ['number'], + 'id': ['number'] + }) + if not user_token['partner_id'] == params['value']['partner_id']: + return self.unauthorized_response() + if not params['valid']: + return self.response(code=400, description=params) + + partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + domain = [ + ('id', '=', params['value']['id']), + ('partner_id', 'in', partner_child_ids) + ] + data = False + sale_order = request.env['sale.order'].search(domain) + if sale_order: + sale_order.state = 'cancel' + data = sale_order.id + return self.response(data) + @http.route(PREFIX_PARTNER + 'sale_order/checkout', auth='public', method=['POST', 'OPTIONS'], csrf=False) def create_partner_sale_order(self, **kw): user_token = self.authenticate() diff --git a/indoteknik_api/models/account_move.py b/indoteknik_api/models/account_move.py index 3c8fd655..5c31f010 100644 --- a/indoteknik_api/models/account_move.py +++ b/indoteknik_api/models/account_move.py @@ -1,6 +1,5 @@ import datetime from odoo import models -import hashlib class AccountMove(models.Model): diff --git a/indoteknik_api/models/rest_api.py b/indoteknik_api/models/rest_api.py index 052800b7..0a15aad1 100644 --- a/indoteknik_api/models/rest_api.py +++ b/indoteknik_api/models/rest_api.py @@ -14,4 +14,7 @@ class RestApi(models.TransientModel): return time def md5_salt(self, value, salt): - return hashlib.md5((salt + '$' + str(value)).encode()).hexdigest() \ No newline at end of file + return hashlib.md5((salt + '$' + str(value)).encode()).hexdigest() + + def md5_salt_valid(self, value, salt, token): + return hashlib.md5((salt + '$' + str(value)).encode()).hexdigest() == token \ No newline at end of file diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index c7d488be..cc2f9586 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -32,6 +32,7 @@ class SaleOrder(models.Model): if context == 'with_detail': res_users = self.env['res.users'] data_with_detail = { + 'purchase_order_file': True if sale_order.partner_purchase_order_file else False, 'payment_term': sale_order.payment_term_id.name or '', 'date_order': self.env['rest.api'].datetime_to_str(sale_order.date_order, '%d/%m/%Y %H:%M:%S'), 'products': [], -- cgit v1.2.3 From ef2f9fefe4df844f5a676d2a166dcd4dfdaa249b Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 6 Feb 2023 16:14:43 +0700 Subject: fix feature --- indoteknik_api/controllers/api_v1/download.py | 28 +++++++++++------ indoteknik_api/controllers/api_v1/sale_order.py | 40 +++++++++++++++++++++++++ indoteknik_api/models/rest_api.py | 29 +++++++++++++++++- indoteknik_api/models/sale_order.py | 3 +- 4 files changed, 89 insertions(+), 11 deletions(-) (limited to 'indoteknik_api') diff --git a/indoteknik_api/controllers/api_v1/download.py b/indoteknik_api/controllers/api_v1/download.py index f12be337..d9353896 100644 --- a/indoteknik_api/controllers/api_v1/download.py +++ b/indoteknik_api/controllers/api_v1/download.py @@ -1,7 +1,6 @@ from .. import controller from odoo import http from odoo.http import request -import base64 class Download(controller.Controller): @@ -13,30 +12,41 @@ class Download(controller.Controller): ('res_field', '=', field), ('res_id', '=', id), ], ['datas', 'mimetype']) - return result if len(result) > 0 else None + return result[0] if len(result) > 0 else None @http.route(PREFIX + 'download/invoice//', auth='none', method=['GET']) def download_invoice(self, id, token): id = int(id) - md5_valid = request.env['rest.api'].md5_salt_valid(id, 'account.move', token) + rest_api = request.env['rest.api'] + md5_valid = rest_api.md5_salt_valid(id, 'account.move', token) if not md5_valid: return self.response('Unauthorized') + account_move = request.env['account.move'].sudo().search_read([('id', '=', id)], ['name']) pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'account.report_invoice')])._render_qweb_pdf([id]) - return request.make_response(pdf, [('Content-Type', 'application/pdf')]) + return rest_api.response_attachment({ + 'content': pdf, + 'mimetype': 'application/pdf', + 'filename': account_move[0]['name'] + }) @http.route(PREFIX + 'download/tax-invoice//', auth='none', method=['GET']) def download_tax_invoice(self, id, token): id = int(id) - md5_valid = request.env['rest.api'].md5_salt_valid(id, 'account.move', token) + rest_api = request.env['rest.api'] + md5_valid = rest_api.md5_salt_valid(id, 'account.move', token) if not md5_valid: return self.response('Unauthorized') + account_move = request.env['account.move'].sudo().search_read([('id', '=', id)], ['name']) attachment = self._get_attachment('account.move', 'efaktur_document', id) - if attachment: - attachment = attachment[0] - return request.make_response(base64.b64decode(attachment['datas']), [('Content-Type', attachment['mimetype'])]) + if attachment and len(account_move) > 0: + return rest_api.response_attachment({ + 'content': attachment['datas'], + 'decode_content': True, + 'mimetype': attachment['mimetype'], + 'filename': account_move[0]['name'], + }) return self.response('Dokumen tidak ditemukan', code=404) - diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 9a4b23d9..1c67d6c5 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -3,6 +3,7 @@ from odoo import http from odoo.http import request import json + class SaleOrder(controller.Controller): prefix = '/api/v1/' PREFIX_PARTNER = prefix + 'partner//' @@ -134,6 +135,45 @@ class SaleOrder(controller.Controller): data = sale_order.id return self.response(data) + @http.route(PREFIX_PARTNER + 'sale_order//download_po/', auth='none', method=['GET']) + def partner_download_po_sale_order(self, id, token): + id = int(id) + + rest_api = request.env['rest.api'] + md5_valid = rest_api.md5_salt_valid(id, 'sale.order', token) + if not md5_valid: + return self.response('Unauthorized') + + sale_order = request.env['sale.order'].sudo().search_read([('id', '=', id)], ['partner_purchase_order_name']) + attachment = rest_api.get_single_attachment('sale.order', 'partner_purchase_order_file', id) + if attachment and len(sale_order) > 0: + return rest_api.response_attachment({ + 'content': attachment['datas'], + 'decode_content': True, + 'mimetype': attachment['mimetype'], + 'filename': sale_order[0]['partner_purchase_order_name'] + }) + return self.response('Dokumen tidak ditemukan', code=404) + + @http.route(PREFIX_PARTNER + 'sale_order//download/', auth='none', method=['GET']) + def partner_download_sale_order(self, id, token): + id = int(id) + + rest_api = request.env['rest.api'] + md5_valid = rest_api.md5_salt_valid(id, 'sale.order', token) + if not md5_valid: + return self.response('Unauthorized') + + sale_order = request.env['sale.order'].sudo().search_read([('id', '=', id)], ['name']) + pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'sale.report_saleorder')])._render_qweb_pdf([id]) + if pdf and len(sale_order) > 0: + return rest_api.response_attachment({ + 'content': pdf, + 'mimetype': 'application/pdf', + 'filename': sale_order[0]['name'] + }) + return self.response('Dokumen tidak ditemukan', code=404) + @http.route(PREFIX_PARTNER + 'sale_order//cancel', auth='public', method=['POST', 'OPTIONS'], csrf=False) def partner_cancel_sale_order(self, **kw): user_token = self.authenticate() diff --git a/indoteknik_api/models/rest_api.py b/indoteknik_api/models/rest_api.py index 0a15aad1..65119b52 100644 --- a/indoteknik_api/models/rest_api.py +++ b/indoteknik_api/models/rest_api.py @@ -1,7 +1,9 @@ from odoo import models +from odoo.http import request import datetime from pytz import timezone import hashlib +import base64 class RestApi(models.TransientModel): @@ -17,4 +19,29 @@ class RestApi(models.TransientModel): return hashlib.md5((salt + '$' + str(value)).encode()).hexdigest() def md5_salt_valid(self, value, salt, token): - return hashlib.md5((salt + '$' + str(value)).encode()).hexdigest() == token \ No newline at end of file + return hashlib.md5((salt + '$' + str(value)).encode()).hexdigest() == token + + def get_single_attachment(self, model, field, id): + domain = [ + ('res_model', '=', model), + ('res_field', '=', field), + ('res_id', '=', id), + ] + fields = ['datas', 'mimetype'] + result = self.env['ir.attachment'].sudo().search_read(domain, fields) + return result[0] if len(result) > 0 else None + + def response_attachment(self, data = {}): + decode_content = data.get('decode_content', False) + if decode_content: + data['content'] = base64.b64decode(data['content']) + + return request.make_response( + data['content'], + [ + ('Content-Type', data['mimetype']), + ('Content-Disposition', 'attachment; filename=%s' % data['filename']), + ('Content-Length', len(data['content'])) + ] + ) + \ No newline at end of file diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index cc2f9586..c3f3dccb 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -6,11 +6,13 @@ class SaleOrder(models.Model): def api_v1_single_response(self, sale_order, context=False): data = { + 'token': self.env['rest.api'].md5_salt(sale_order.id, 'sale.order'), 'id': sale_order.id, 'name': sale_order.name, 'sales': sale_order.user_id.name, 'amount_total': sale_order.amount_total, 'purchase_order_name': sale_order.partner_purchase_order_name, + 'purchase_order_file': True if sale_order.partner_purchase_order_file else False, 'invoice_count': sale_order.invoice_count, 'status': 'draft', } @@ -32,7 +34,6 @@ class SaleOrder(models.Model): if context == 'with_detail': res_users = self.env['res.users'] data_with_detail = { - 'purchase_order_file': True if sale_order.partner_purchase_order_file else False, 'payment_term': sale_order.payment_term_id.name or '', 'date_order': self.env['rest.api'].datetime_to_str(sale_order.date_order, '%d/%m/%Y %H:%M:%S'), 'products': [], -- cgit v1.2.3 From e62b025b68dcba1b079d6e028458d99116f66946 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 7 Feb 2023 13:55:39 +0700 Subject: ip lookup and record request --- .../controllers/__pycache__/controller.cpython-38.pyc.3117987094576 | 0 indoteknik_api/controllers/controller.py | 1 + 2 files changed, 1 insertion(+) create mode 100644 indoteknik_api/controllers/__pycache__/controller.cpython-38.pyc.3117987094576 (limited to 'indoteknik_api') diff --git a/indoteknik_api/controllers/__pycache__/controller.cpython-38.pyc.3117987094576 b/indoteknik_api/controllers/__pycache__/controller.cpython-38.pyc.3117987094576 new file mode 100644 index 00000000..e69de29b diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index c90d3ff1..ffa4e24b 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -86,6 +86,7 @@ class Controller(http.Controller): return time def response(self, data=[], code=200, description='OK'): + request.env['user.activity.log'].record_activity() response = { 'status': { 'code': code, -- cgit v1.2.3 From 90442b65e48d6a1e09c7bd23c17f478ce25ba0ca Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 7 Feb 2023 13:56:32 +0700 Subject: delete pycache --- .../controllers/__pycache__/controller.cpython-38.pyc.3117987094576 | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 indoteknik_api/controllers/__pycache__/controller.cpython-38.pyc.3117987094576 (limited to 'indoteknik_api') diff --git a/indoteknik_api/controllers/__pycache__/controller.cpython-38.pyc.3117987094576 b/indoteknik_api/controllers/__pycache__/controller.cpython-38.pyc.3117987094576 deleted file mode 100644 index e69de29b..00000000 -- cgit v1.2.3 From d2fcc3208afcab10502955f2e6554383ff376135 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 7 Feb 2023 14:29:01 +0700 Subject: listen request on image --- indoteknik_api/controllers/controller.py | 1 + 1 file changed, 1 insertion(+) (limited to 'indoteknik_api') diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index ffa4e24b..59885148 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -150,4 +150,5 @@ class Controller(http.Controller): def get_image(self, model, field, id): model = request.env[model].sudo().search([('id', '=', id)], limit=1) image = model[field] if model[field] else '' + request.env['user.activity.log'].record_activity() return request.make_response(base64.b64decode(image), [('Content-Type', 'image/jpg')]) -- cgit v1.2.3