diff options
| -rw-r--r-- | indoteknik_api/controllers/api_v1/product.py | 48 | ||||
| -rwxr-xr-x | indoteknik_custom/__manifest__.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/models/__init__.py | 2 | ||||
| -rw-r--r-- | indoteknik_custom/models/account_move.py | 17 | ||||
| -rw-r--r-- | indoteknik_custom/models/account_move_due_extension.py | 142 | ||||
| -rw-r--r-- | indoteknik_custom/models/automatic_purchase.py | 7 | ||||
| -rw-r--r-- | indoteknik_custom/models/product_sla.py | 87 | ||||
| -rwxr-xr-x | indoteknik_custom/models/product_template.py | 66 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 10 | ||||
| -rw-r--r-- | indoteknik_custom/models/res_partner.py | 9 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 43 | ||||
| -rw-r--r-- | indoteknik_custom/models/token_storage.py | 9 | ||||
| -rwxr-xr-x | indoteknik_custom/security/ir.model.access.csv | 4 | ||||
| -rw-r--r-- | indoteknik_custom/views/account_move.xml | 25 | ||||
| -rw-r--r-- | indoteknik_custom/views/account_move_views.xml | 3 | ||||
| -rw-r--r-- | indoteknik_custom/views/product_sla.xml | 59 | ||||
| -rwxr-xr-x | indoteknik_custom/views/purchase_order.xml | 7 | ||||
| -rw-r--r-- | indoteknik_custom/views/res_partner.xml | 1 |
18 files changed, 454 insertions, 86 deletions
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py index 54b039c7..8803bae3 100644 --- a/indoteknik_api/controllers/api_v1/product.py +++ b/indoteknik_api/controllers/api_v1/product.py @@ -4,6 +4,7 @@ from odoo.http import request from datetime import datetime, timedelta import ast import logging +import math _logger = logging.getLogger(__name__) @@ -11,6 +12,49 @@ _logger = logging.getLogger(__name__) class Product(controller.Controller): prefix = '/api/v1/' + @http.route(prefix + 'product_variant/<id>/stock', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def get_product_template_stock_by_id(self, **kw): + id = int(kw.get('id')) + product = request.env['product.product'].search([('id', '=', id)], limit=1) + product_sla = request.env['product.sla'].search([('product_variant_id', '=', id)], limit=1) + + qty_available = product.qty_onhand_bandengan + qty_available -= 10 + if qty_available < 10: + qty_available = 0 + + qty = 0 + sla_date = '-' + + is_altama_product = product.x_manufacture.id in [10,122,89] + if is_altama_product: + try: + qty_altama = request.env['product.template'].get_stock_altama(product.default_code) + qty_altama -= int(qty_altama * 0.1) + qty_altama = math.ceil(float(qty_altama)) + qty = qty_altama + if qty_available > 10: + qty += qty_available + sla_date = '1 Hari' + elif qty_altama > 0: + sla_date = '2-4 Hari' + else: + sla_date = 'Indent' + except: + print('error') + else: + qty = qty_available + sla_date = product_sla.sla or '-' + + data = { + 'qty': qty, + 'sla_date': sla_date, + } + + return self.response(data, headers=[('Cache-Control', 'max-age=180, private')]) + + @http.route(prefix + 'product/template/price/<id>', auth='public', methods=['GET', 'OPTIONS']) def get_product_template_price_by_id(self, **kw): if not self.authenticate(): @@ -54,7 +98,7 @@ class Product(controller.Controller): if not self.authenticate(): return self.response(code=401, description='Unauthorized') id = kw.get('id') - partner_id = int(kw.get('partner_id', 0)) + partner_id = int(kw.get('partner_id', 0)) product_product = request.env['product.product'].search([('id', '=', id)], limit=1) data = { @@ -90,7 +134,7 @@ class Product(controller.Controller): # ('create_date', '>=', delta_time), ] new_products = request.env['product.template'].search(query_products, order='create_date desc', limit=limit_new_products) - brands = [] + brands = [] for product in new_products: brands.append(product.x_manufacture) brands = list(dict.fromkeys(brands)) diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 5b0c4e41..4fa736f6 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -77,6 +77,7 @@ 'views/brand_vendor.xml', 'views/requisition.xml', 'views/landedcost.xml', + 'views/product_sla.xml', 'views/voucher.xml', 'report/report.xml', 'report/report_banner_banner.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 3a27072c..9e4d2cf9 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -63,5 +63,7 @@ from . import procurement_monitoring_detail from . import brand_vendor from . import manufacturing from . import requisition +from . import token_storage +from . import product_sla from . import account_move_due_extension from . import voucher
\ No newline at end of file diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index c2e93632..bc6061ee 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -1,6 +1,9 @@ from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date +import logging + +_logger = logging.getLogger(__name__) class AccountMove(models.Model): @@ -13,6 +16,17 @@ class AccountMove(models.Model): resi_tukar_faktur = fields.Char(string='Resi Faktur') date_terima_tukar_faktur = fields.Date(string='Terima Faktur') shipper_faktur_id = fields.Many2one('delivery.carrier', string='Shipper Faktur') + due_extension = fields.Integer(string='Due Extension', default=0) + new_due_date = fields.Date(string='New Due') + counter = fields.Integer(string="Counter", default=0) + due_line = fields.One2many('due.extension.line', 'invoice_id', compute='_compute_due_line', string='Due Extension Lines') + + def _compute_due_line(self): + for invoice in self: + invoice.due_line = self.env['due.extension.line'].search([ + ('invoice_id', '=', invoice.id), + ('due_id.approval_status', '=', 'approved') + ]) def unlink(self): res = super(AccountMove, self).unlink() @@ -70,6 +84,8 @@ class AccountMove(models.Model): invoice_day_to_due = 0 if invoice.payment_state not in ['paid', 'in_payment', 'reversed'] and invoice.invoice_date_due: invoice_day_to_due = invoice.invoice_date_due - date.today() + if invoice.new_due_date: + invoice_day_to_due = invoice.new_due_date - date.today() invoice_day_to_due = invoice_day_to_due.days invoice.invoice_day_to_due = invoice_day_to_due @@ -98,3 +114,4 @@ class AccountMove(models.Model): add_days += line.days due_date = tukar_date + timedelta(days=add_days) invoice.invoice_date_due = due_date +
\ No newline at end of file diff --git a/indoteknik_custom/models/account_move_due_extension.py b/indoteknik_custom/models/account_move_due_extension.py index 93dfe62b..43207534 100644 --- a/indoteknik_custom/models/account_move_due_extension.py +++ b/indoteknik_custom/models/account_move_due_extension.py @@ -27,6 +27,11 @@ class DueExtension(models.Model): ('7', '7 Hari'), ('14', '14 Hari'), ], string='Day Extension', help='Menambah Due Date yang sudah limit dari hari ini', tracking=True) + counter = fields.Integer(string="Counter", compute='_compute_counter') + + def _compute_counter(self): + for due in self: + due.counter = due.partner_id.counter @api.model def create(self, vals): @@ -57,67 +62,69 @@ class DueExtension(models.Model): raise UserError('Hanya Finance yang bisa cancel') def approve_new_due(self): - if self.env.user.is_accounting: - self.is_approve = True - self.approval_status = 'approved' + if not self.env.user.is_accounting: + raise UserError('Hanya Finance Yang Bisa Approve') + + if self.approval_status == 'approved': + raise UserError('Document ini sudah di approve') + + self.is_approve = True + self.approval_status = 'approved' - if self.partner_id: - if self.day_extension: - day_extension = int(self.day_extension) - new_due = date.today() + timedelta(days=day_extension) - - for line in self.due_line: - line.invoice_id.invoice_date_due = new_due - - if self.order_id._notification_margin_leader(): - self.order_id.approval_status = 'pengajuan2' - return self.order_id._notification_has_margin_leader() + self.partner_id.counter+=1 - if self.order_id._notification_margin_manager(): - self.order_id.approval_status = 'pengajuan1' - return self.order_id._notification_has_margin_manager() + day_extension = int(self.day_extension) + if self.partner_id: + new_due = date.today() + timedelta(days=day_extension) - sales = self.env['sale.order'].search([ - ('id', '=', self.order_id.id) - ]) - - # sales.state = 'sale' - sales.action_confirm() - self.order_id.due_id = self.id - else: - raise UserError('Hanya Finance Yang Bisa Approve') + for line in self.due_line: + line.invoice_id.new_due_date = new_due + line.invoice_id.due_extension = day_extension + + if self.order_id._notification_margin_leader(): + self.order_id.approval_status = 'pengajuan2' + return self.order_id._notification_has_margin_leader() + + if self.order_id._notification_margin_manager(): + self.order_id.approval_status = 'pengajuan1' + return self.order_id._notification_has_margin_manager() + + sales = self.env['sale.order'].browse(self.order_id.id) + + sales.action_confirm() + self.order_id.due_id = self.id def generate_due_line(self): - partners = [] - partners += self.partner_id.child_ids - partners.append(self.partner_id) - - - for partner in partners: - query = [ - ('partner_id', '=', partner.id), - ('state', '=', 'posted'), - ('move_type', '=', 'out_invoice'), - ('amount_residual_signed', '>', 0) - ] - invoices = self.env['account.move'].search(query, order='invoice_date') - count = 0 - - for invoice in invoices: - if invoice.invoice_day_to_due < 0: - self.env['due.extension.line'].create([{ - 'due_id': self.id, - 'partner_id': invoice.partner_id.id, - 'invoice_id': invoice.id, - 'date_invoice': invoice.invoice_date, - 'efaktur_id': invoice.efaktur_id.id, - 'reference': invoice.ref, - 'total_amt': invoice.amount_total, - 'open_amt': invoice.amount_residual_signed, - 'due_date': invoice.invoice_date_due - }]) - count += 1 - _logger.info("Due Extension Line generated %s" % count) + partners = self.partner_id.get_child_ids() + + query = [ + ('partner_id', 'in', partners), + ('state', '=', 'posted'), + ('move_type', '=', 'out_invoice'), + ('amount_residual_signed', '>', 0) + ] + invoices = self.env['account.move'].search(query, order='invoice_date') + count = 0 + + for invoice in invoices: + day_to_due = invoice.invoice_day_to_due + invoice.due_extension + if day_to_due < 0: + self.env['due.extension.line'].create([{ + 'due_id': self.id, + 'partner_id': invoice.partner_id.id, + 'invoice_id': invoice.id, + 'date_invoice': invoice.invoice_date, + 'efaktur_id': invoice.efaktur_id.id, + 'reference': invoice.ref, + 'total_amt': invoice.amount_total, + 'open_amt': invoice.amount_residual_signed + }]) + count += 1 + invoice.counter+=1 + + _logger.info("Due Extension Line generated %s" % count) + + def unlink(self): res = super(DueExtension, self).unlink() if not self._name == 'due.extension': @@ -131,6 +138,12 @@ class DueExtensionLine(models.Model): _order = 'due_id, id' due_id = fields.Many2one('due.extension', string='Due Ref', required=True, ondelete='cascade', index=True, copy=False) + due_description = fields.Text(string="Description", compute="_compute_due_description") + due_approval_status = fields.Selection([ + ('pengajuan', 'Pengajuan'), + ('approved', 'Approved'), + ], string="Approval Status", compute="_compute_due_approval_status") + due_day_extension = fields.Char(string="Day Extension", compute="_compute_due_day_extension") partner_id = fields.Many2one('res.partner', string='Customer') invoice_id = fields.Many2one('account.move', string='Invoice') date_invoice = fields.Date(string='Invoice Date') @@ -141,11 +154,26 @@ class DueExtensionLine(models.Model): due_date = fields.Date(string='Due Date', compute="_compute_due_date") day_to_due = fields.Integer(string='Day To Due', compute="_compute_day_to_due") + def _compute_due_description(self): + for line in self: + line.due_description = line.due_id.description + + def _compute_due_approval_status(self): + for line in self: + line.due_approval_status = line.due_id.approval_status + + def _compute_due_day_extension(self): + for line in self: + line.due_day_extension = line.due_id.day_extension + def _compute_day_to_due(self): for line in self: line.day_to_due = line.invoice_id.invoice_day_to_due def _compute_due_date(self): for line in self: - line.due_date = line.invoice_id.invoice_date_due + if line.invoice_id.new_due_date: + line.due_date = line.invoice_id.new_due_date + else: + line.due_date = line.invoice_id.invoice_date_due diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 87319bf6..e21b411d 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -59,11 +59,18 @@ class AutomaticPurchase(models.Model): # new_po = self.env['purchase.order'].create([param_header]) brand_id = product.brand_id.id count += 10 + + qty_available = product.product_id.qty_onhand_bandengan + product.product_id.qty_incoming_bandengan - product.product_id.outgoing_qty + suggest = 'harus beli' + if qty_available > product.qty_purchase: + suggest = 'masih cukup' param_line = { 'order_id': new_po.id, 'sequence': count, 'product_id': product.product_id.id, 'product_qty': product.qty_purchase, + 'qty_available_store': qty_available, + 'suggest': suggest, 'product_uom_qty': product.qty_purchase, 'price_unit': product.last_price, } diff --git a/indoteknik_custom/models/product_sla.py b/indoteknik_custom/models/product_sla.py new file mode 100644 index 00000000..f969502f --- /dev/null +++ b/indoteknik_custom/models/product_sla.py @@ -0,0 +1,87 @@ +from odoo import models, api, fields +from odoo.exceptions import AccessError, UserError, ValidationError +from datetime import timedelta, date +import logging +import math +_logger = logging.getLogger(__name__) + + +class ProductSla(models.Model): + _name = 'product.sla' + _description = 'Product Sla' + _rec_name = 'product_variant_id' + + product_variant_id = fields.Many2one('product.product',string='Product') + avg_leadtime = fields.Char(string='AVG Leadtime', readonly=True) + leadtime = fields.Char(string='Leadtime', readonly=True) + sla = fields.Char(string='SLA', readonly=True) + version = fields.Integer(string="Version", compute="_compute_version") + + def _compute_version(self): + for sla in self: + sla.version = sla.product_variant_id.sla_version + + def generate_product_variant_id_sla(self, limit=5000): + # Filter produk non-Altama + products = self.env['product.product'].search([ + ('x_manufacture', 'not in', [10, 122, 89]), + ('location_id', '=', 57), + ('stock_move_ids', '!=', False), + ], order='sla_version asc', limit=limit) + + i = 1 + for product in products: + _logger.info(f'Product SLA: {i}/{len(products)}') + i += 1 + product.sla_version += 1 + + product_sla = self.search([('product_variant_id', '=', product.id)], limit=1) + if not product_sla: + product_sla = self.env['product.sla'].create({ + 'product_variant_id': product.id, + }) + + product_sla.generate_product_sla() + + def generate_product_sla(self): + self.avg_leadtime = '-' + self.sla = '-' + + product = self.product_variant_id + + qty_available = 0 + qty_available = product.qty_onhand_bandengan + qty_available -= 10 + + if qty_available < 10: + qty_available = 0 + + if qty_available > 10: + self.sla = '1 Hari' + + query = [ + ('product_id', '=', product.id), + ('picking_id', '!=', False), + ('picking_id.location_id', '=', 57), + ('picking_id.state', 'not in', ['cancel']) + ] + picking = self.env['stock.move.line'].search(query) + leadtimes=[] + for stock in picking: + date_delivered = stock.picking_id.driver_departure_date + date_so_confirmed = stock.picking_id.sale_id.date_order + if date_delivered and date_so_confirmed: + leadtime = date_delivered - date_so_confirmed + leadtime_in_days = leadtime.days + leadtimes.append(leadtime_in_days) + + if len(leadtimes) > 0: + avg_leadtime = sum(leadtimes) / len(leadtimes) + rounded_leadtime = math.ceil(avg_leadtime) + self.avg_leadtime = rounded_leadtime + if rounded_leadtime >= 1 and rounded_leadtime <= 5: + self.sla = '3-6 Hari' + elif rounded_leadtime >= 6 and rounded_leadtime <= 10: + self.sla = '4-12 Hari' + elif rounded_leadtime >= 11: + self.sla = 'Indent'
\ No newline at end of file diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index a4f8f031..1a83b702 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -2,6 +2,8 @@ from odoo import fields, models, api from datetime import datetime, timedelta from odoo.exceptions import AccessError, UserError, ValidationError import logging +import requests +import json _logger = logging.getLogger(__name__) @@ -190,7 +192,70 @@ class ProductTemplate(models.Model): product.product_rating = rate product.last_calculate_rating = current_time + def _get_stock_website(self): + qty = self._get_stock_altama() + print(qty) + def get_stock_altama(self, item_code): + current_time = datetime.now() + current_time = current_time.strftime('%Y-%m-%d %H:%M:%S') + query = [('source', '=', 'altama'), ('expired_date', '>', current_time)] + token_data = self.env['token.storage'].search(query, order='expired_date desc',limit=1) + if not token_data: + token_data = self._get_new_token_altama() + token = token_data['access_token'] + else: + token = token_data.access_token + + url = "https://erpapi.altama.co.id/erp/api/stock/buffer/btob" + auth = "Bearer "+token + headers = { + 'Content-Type': 'application/json', + 'Authorization': auth, + } + json_data = { + 'type_search': 'Item_code', + 'search_key':[item_code], + } + response = requests.post(url, headers=headers, json=json_data) + datas = json.loads(response.text)['data'] + qty = 0 + for data in datas: + availability = int(data['availability']) # Mengonversi ke tipe data int + qty += availability # Mengakumulasi qty dari setiap data + + return qty + + def _get_new_token_altama(self): + url = "https://kc.altama.co.id/realms/altama/protocol/openid-connect/token" + auth = 'Basic SW5kb3Rla25pa19DbGllbnQ6Vm1iZExER1ZUS3RuVlRQdkU1MXRvRzdiTW51TE1WRVI=' + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': auth, + } + data = { + 'grant_type': 'client_credentials', + } + + response = requests.post(url, headers=headers, data=data).json() + lookup_json = json.dumps(response, indent=4, sort_keys=True) + token = json.loads(lookup_json)['access_token'] + expires_in = json.loads(lookup_json)['expires_in'] + + current_time = datetime.now() + delta_time = current_time + timedelta(seconds=int(expires_in)) + + current_time = current_time.strftime('%Y-%m-%d %H:%M:%S') + delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') + + values = { + 'source': 'altama', + 'access_token': token, + 'expires_in': expires_in, + 'expired_date': delta_time, + } + self.env['token.storage'].create([values]) + return values class ProductProduct(models.Model): @@ -213,6 +278,7 @@ class ProductProduct(models.Model): material = fields.Char(string='Material') qty_onhand_bandengan = fields.Float(string='Qty Incoming Bandengan', compute='_get_qty_onhand_bandengan') qty_incoming_bandengan = fields.Float(string='Qty Incoming Bandengan', compute='_get_qty_incoming_bandengan') + sla_version = fields.Integer(string="SLA Version", default=0) def _get_qty_incoming_bandengan(self): for product in self: diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 1eb76370..7091bb72 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -215,6 +215,16 @@ class PurchaseOrder(models.Model): else: self.approval_status = 'pengajuan1' + def re_calculate(self): + for line in self.order_line: + sale_order_line = self.env['sale.order.line'].search([ + ('product_id', '=', line.product_id.id), + ('order_id', '=', line.order_id.sale_order_id.id) + ], limit=1, order='price_reduce_taxexcl') + for so_line in sale_order_line: + unit_price = line.price_unit + so_line.purchase_price = unit_price + def button_cancel(self): res = super(PurchaseOrder, self).button_cancel() self.approval_status = False diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index bdeb8a2c..1695639d 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -18,6 +18,15 @@ class ResPartner(models.Model): ('nonpkp', 'Non PKP') ]) sppkp = fields.Char(string="SPPKP") + counter = fields.Integer(string="Counter", default=0) + + def get_child_ids(self): + partner = self.env['res.partner'].search([('id', '=', self.id)], limit=1) + partner_child_ids = [x['id'] for x in partner.child_ids] + [partner.id] + if partner.parent_id: + partner_child_ids += [x['id'] for x in partner.parent_id.child_ids] + partner_child_ids += [partner.parent_id.id] + return partner_child_ids def unlink(self): if self._name == 'res.partner': diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 1bdc0cb6..e151bf22 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -8,6 +8,7 @@ import string import requests import math import json +from datetime import timedelta, date _logger = logging.getLogger(__name__) @@ -391,26 +392,28 @@ class SaleOrder(models.Model): if self.due_id and self.due_id.is_approve == False: raise UserError('Document Over Due Yang Anda Buat Belum Di Approve') - if not self.env.user.is_leader and not self.env.user.is_sales_manager: - query = [ - ('partner_id', '=', parent_id), - ('state', '=', 'posted'), - ('move_type', '=', 'out_invoice'), - ('amount_residual_signed', '>', 0) - ] - invoices = self.env['account.move'].search(query, order='invoice_date') - due_extension = self.env['due.extension'].create([{ - 'partner_id': parent_id, - 'day_extension': '3', - 'order_id': self.id, - }]) - due_extension.generate_due_line() - self.due_id = due_extension.id - if len(self.due_id.due_line) > 0: - return True - else: - due_extension.unlink() - return False + query = [ + ('partner_id', '=', parent_id), + ('state', '=', 'posted'), + ('move_type', '=', 'out_invoice'), + ('amount_residual_signed', '>', 0) + ] + invoices = self.env['account.move'].search(query, order='invoice_date') + + if invoices: + if not self.env.user.is_leader and not self.env.user.is_sales_manager: + due_extension = self.env['due.extension'].create([{ + 'partner_id': parent_id, + 'day_extension': '3', + 'order_id': self.id, + }]) + due_extension.generate_due_line() + self.due_id = due_extension.id + if len(self.due_id.due_line) > 0: + return True + else: + due_extension.unlink() + return False def _notification_margin_leader(self): if self.total_percent_margin <= 15 and not self.env.user.is_leader: diff --git a/indoteknik_custom/models/token_storage.py b/indoteknik_custom/models/token_storage.py new file mode 100644 index 00000000..0eef7f20 --- /dev/null +++ b/indoteknik_custom/models/token_storage.py @@ -0,0 +1,9 @@ +from odoo import fields, models + +class TokenStorage(models.Model): + + _name = 'token.storage' + source = fields.Char(string='Source') + access_token = fields.Char(string='Access Token') + expires_in = fields.Integer(string='Expires In') + expired_date = fields.Datetime(string='Expired Date') diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 7cacf2bb..2b269417 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -54,4 +54,6 @@ 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 -access_voucher,access.voucher,model_voucher,,1,1,1,1
\ No newline at end of file +access_token_storage,access.token_storage,model_token_storage,,1,1,1,1 +access_product_sla,access.product_sla,model_product_sla,,1,1,1,1 +access_voucher,access.voucher,model_voucher,,1,1,1,1 diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 9faf3149..a1d3eaaa 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -15,7 +15,21 @@ <field name="shipper_faktur_id"/> <field name="resi_tukar_faktur"/> <field name="date_terima_tukar_faktur"/> + <field name="due_extension"/> + <field name="counter"/> </field> + <notebook position="inside"> + <page string="Due Extension"> + <field name="due_line"> + <tree> + <field name="due_id"/> + <field name="due_description"/> + <field name="due_day_extension"/> + <field name="due_approval_status"/> + </tree> + </field> + </page> + </notebook> </field> </record> @@ -30,13 +44,14 @@ </field> <field name="invoice_date_due" position="after"> <field name="invoice_day_to_due" attrs="{'invisible': [['payment_state', 'in', ('paid', 'in_payment', 'reversed')]]}"/> + <field name="due_extension" optional="hide"/> </field> <field name="payment_state" position="after"> - <field name="invoice_payment_term_id"/> - <field name="date_kirim_tukar_faktur"/> - <field name="shipper_faktur_id" optional="1"/> - <field name="resi_tukar_faktur" optional="1"/> - <field name="date_terima_tukar_faktur"/> + <field name="invoice_payment_term_id" optional="hide"/> + <field name="date_kirim_tukar_faktur" optional="hide"/> + <field name="shipper_faktur_id" optional="hide"/> + <field name="resi_tukar_faktur" optional="hide"/> + <field name="date_terima_tukar_faktur" optional="hide"/> </field> </field> </record> diff --git a/indoteknik_custom/views/account_move_views.xml b/indoteknik_custom/views/account_move_views.xml index 02926682..fee94b42 100644 --- a/indoteknik_custom/views/account_move_views.xml +++ b/indoteknik_custom/views/account_move_views.xml @@ -4,7 +4,7 @@ <field name="name">due.extension.tree</field> <field name="model">due.extension</field> <field name="arch" type="xml"> - <tree create="false"> + <tree default_order="create_date desc" create="0"> <field name="number"/> <field name="partner_id"/> <field name="day_extension"/> @@ -61,6 +61,7 @@ <group> <field name="is_approve" readonly="1"/> <field name="order_id" readonly="1"/> + <field name="counter" readonly="1"/> <field name="approval_status" readonly="1"/> </group> </group> diff --git a/indoteknik_custom/views/product_sla.xml b/indoteknik_custom/views/product_sla.xml new file mode 100644 index 00000000..59d58568 --- /dev/null +++ b/indoteknik_custom/views/product_sla.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<odoo> + <record id="product_sla_tree" model="ir.ui.view"> + <field name="name">product.sla.tree</field> + <field name="model">product.sla</field> + <field name="arch" type="xml"> + <tree create="false"> + <field name="product_variant_id"/> + <field name="avg_leadtime"/> + <field name="sla"/> + </tree> + </field> + </record> + + <record id="product_sla_form" model="ir.ui.view"> + <field name="name">product.sla.form</field> + <field name="model">product.sla</field> + <field name="arch" type="xml"> + <form> + <sheet string="Product Sla"> + <group> + <group> + <field name="product_variant_id"/> + <field name="avg_leadtime"/> + <field name="sla"/> + <field name="version"/> + </group> + </group> + </sheet> + </form> + </field> + </record> + + <record id="product_sla_action" model="ir.actions.act_window"> + <field name="name">Product Sla</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">product.sla</field> + <field name="view_mode">tree,form</field> + </record> + + <record id="product_sla_generate_cron" model="ir.cron"> + <field name="name">Product SLA: Generate</field> + <field name="interval_number">8</field> + <field name="interval_type">minutes</field> + <field name="numbercall">-1</field> + <field name="doall" eval="False"/> + <field name="model_id" ref="model_product_sla"/> + <field name="code">model.generate_product_variant_id_sla(limit=150)</field> + <field name="state">code</field> + <field name="priority">100</field> + <field name="active">True</field> + </record> + + <menuitem id="menu_product_sla" + name="Product Sla" + action="product_sla_action" + parent="sale.product_menu_catalog" + sequence="7"/> +</odoo>
\ No newline at end of file diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 5b0c99ef..4efa8cf4 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -42,6 +42,11 @@ <field name="total_so_margin"/> <field name="total_percent_margin"/> <field name="total_so_percent_margin"/> + <button name="re_calculate" + string="Re Calculate" + type="object" + attrs="{'invisible': [('approval_status', '=', 'approved')]}" + /> </field> <field name="product_id" position="before"> <field name="line_no" attrs="{'readonly': 1}" optional="hide"/> @@ -59,6 +64,8 @@ </page> <field name="fiscal_position_id" position="after"> <field name="note_description"/> + <field name="total_so_percent_margin"/> + </field> </field> </record> diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index c77d942b..d609fdd5 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -8,6 +8,7 @@ <field name="arch" type="xml"> <field name="npwp" position="after"> <field name="sppkp"/> + <field name="counter"/> <field name="reference_number"/> </field> <field name="industry_id" position="after"> |
