From 35e308b24e8a9ae6c158d65c68d4a30e0be40cba Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 10 Oct 2023 09:27:49 +0700 Subject: Add sync to solr on model - promotion program - promotion program line --- indoteknik_custom/models/__init__.py | 2 +- indoteknik_custom/models/solr/__init__.py | 4 +- indoteknik_custom/models/solr/promotion_program.py | 61 +++++++++++++++++++++ .../models/solr/promotion_program_line.py | 62 ++++++++++++++++++++++ 4 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 indoteknik_custom/models/solr/promotion_program.py create mode 100644 indoteknik_custom/models/solr/promotion_program_line.py diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 95defed6..2eb4b9b9 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -81,11 +81,11 @@ from . import po_sync_price from . import base_import_import from . import product_attribute from . import mrp_production +from . import promotion from . import solr from . import cost_centre from . import account_account from . import account_move_line from . import stock_scheduler_compute -from . import promotion from . import sale_orders_multi_update from . import quotation_so_multi_update \ No newline at end of file diff --git a/indoteknik_custom/models/solr/__init__.py b/indoteknik_custom/models/solr/__init__.py index f2d13116..606c0035 100644 --- a/indoteknik_custom/models/solr/__init__.py +++ b/indoteknik_custom/models/solr/__init__.py @@ -8,4 +8,6 @@ from . import website_categories_homepage from . import x_manufactures from . import x_banner_banner from . import product_public_category -from . import x_banner_category \ No newline at end of file +from . import x_banner_category +from . import promotion_program +from . import promotion_program_line \ No newline at end of file diff --git a/indoteknik_custom/models/solr/promotion_program.py b/indoteknik_custom/models/solr/promotion_program.py new file mode 100644 index 00000000..c288c165 --- /dev/null +++ b/indoteknik_custom/models/solr/promotion_program.py @@ -0,0 +1,61 @@ +from odoo import models, api +from datetime import datetime +from pytz import timezone +from typing import Type +import pysolr + + +class PromotionProgram(models.Model): + _inherit = 'promotion.program' + _solr_schema = 'promotion_programs' + + def solr(self) -> Type[pysolr.Solr]: + return self.env['apache.solr'].connect(self._solr_schema) + + def _create_solr_queue(self, function_name: str): + for rec in self: + self.env['apache.solr.queue'].create_unique({ + 'res_model': self._name, + 'res_id': rec.id, + 'function_name': function_name + }) + + def _sync_to_solr(self): + ir_attachment = self.env['ir.attachment'] + solr_model = self.env['apache.solr'] + + for rec in self: + document = solr_model.get_doc(self._solr_schema, rec.id) + document.update({ + 'id': rec.id, + 'name_s': rec.name, + 'banner_s': ir_attachment.api_image(self._name, 'banner', rec.id) if rec.banner else '', + 'keywords': [x.name for x in rec.keyword_ids], + 'line_ids': [x.id for x in rec.program_line], + 'start_time_s': self._time_format(rec.start_time), + 'end_time_s': self._time_format(rec.end_time), + 'applies_to_s': rec.applies_to, + 'icon_s': ir_attachment.api_image(self._name, 'icon', rec.id) if rec.icon else '', + 'icon_top_s': ir_attachment.api_image(self._name, 'icon_top', rec.id) if rec.icon_top else '', + 'icon_bottom_s': ir_attachment.api_image(self._name, 'icon_bottom', rec.id) if rec.icon_bottom else '', + }) + + self.solr().add([document]) + + self.solr().commit() + + def _time_format(self, object) -> str: + time = '' + tz_jakarta = timezone('Asia/Jakarta') + if isinstance(object, datetime): + time = object.astimezone(tz_jakarta).strftime("%Y-%m-%d %H:%M:%S") + return time + + @api.model + def create(self, vals): + self._create_solr_queue('_sync_to_solr') + return super(PromotionProgram, self).create(vals) + + def write(self, vals): + self._create_solr_queue('_sync_to_solr') + return super(PromotionProgram, self).write(vals) diff --git a/indoteknik_custom/models/solr/promotion_program_line.py b/indoteknik_custom/models/solr/promotion_program_line.py new file mode 100644 index 00000000..581783d1 --- /dev/null +++ b/indoteknik_custom/models/solr/promotion_program_line.py @@ -0,0 +1,62 @@ +from odoo import models, api +from typing import Type +import pysolr, json + + +class PromotionProgramLine(models.Model): + _inherit = 'promotion.program.line' + _solr_schema = 'promotion_program_lines' + + def solr(self) -> Type[pysolr.Solr]: + return self.env['apache.solr'].connect(self._solr_schema) + + def _create_solr_queue(self, function_name: str): + for rec in self: + self.env['apache.solr.queue'].create_unique({ + 'res_model': self._name, + 'res_id': rec.id, + 'function_name': function_name + }) + + def _sync_to_solr(self): + solr_model = self.env['apache.solr'] + + for rec in self: + document = solr_model.get_doc(self._solr_schema, rec.id) + + products = [{ + 'product_id': x.product_id.id, + 'qty': x.qty + } for x in rec.product_ids] + + free_products = [{ + 'product_id': x.product_id.id, + 'qty': x.qty + } for x in rec.free_product_ids] + + document.update({ + 'id': rec.id, + 'program_id': rec.program_id.id, + 'name_s': rec.name, + 'image_s': self.env['ir.attachment'].api_image(self._name, 'image', rec.id) if rec.image else '', + 'type_s': json.dumps(rec._res_promotion_type()), + 'package_limit_i': rec.package_limit, + 'package_limit_user_i': rec.package_limit_user, + 'package_limit_trx_i': rec.package_limit_trx, + 'price_f': rec.price, + 'products_s': json.dumps(products), + 'free_products_s': json.dumps(free_products) + }) + + self.solr().add([document]) + + self.solr().commit() + + @api.model + def create(self, vals): + self._create_solr_queue('_sync_to_solr') + return super(PromotionProgramLine, self).create(vals) + + def write(self, vals): + self._create_solr_queue('_sync_to_solr') + return super(PromotionProgramLine, self).write(vals) \ No newline at end of file -- cgit v1.2.3 From ce3f0c1b8f9fee54caf2047190151b6caf80664c Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 10 Oct 2023 09:53:01 +0700 Subject: Update program line response --- indoteknik_custom/models/solr/promotion_program_line.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/solr/promotion_program_line.py b/indoteknik_custom/models/solr/promotion_program_line.py index 581783d1..e5f22e74 100644 --- a/indoteknik_custom/models/solr/promotion_program_line.py +++ b/indoteknik_custom/models/solr/promotion_program_line.py @@ -36,7 +36,7 @@ class PromotionProgramLine(models.Model): document.update({ 'id': rec.id, - 'program_id': rec.program_id.id, + 'program_id_i': rec.program_id.id, 'name_s': rec.name, 'image_s': self.env['ir.attachment'].api_image(self._name, 'image', rec.id) if rec.image else '', 'type_s': json.dumps(rec._res_promotion_type()), @@ -44,7 +44,9 @@ class PromotionProgramLine(models.Model): 'package_limit_user_i': rec.package_limit_user, 'package_limit_trx_i': rec.package_limit_trx, 'price_f': rec.price, + 'product_ids': [x.product_id.id for x in rec.product_ids], 'products_s': json.dumps(products), + 'free_product_ids': [x.product_id.id for x in rec.free_product_ids], 'free_products_s': json.dumps(free_products) }) -- cgit v1.2.3 From a4a1461c3b6603c1a4943935ed45f1a3ea9b80ed Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 10 Oct 2023 10:41:47 +0700 Subject: Add program line get stock API --- indoteknik_api/controllers/api_v1/promotion.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/indoteknik_api/controllers/api_v1/promotion.py b/indoteknik_api/controllers/api_v1/promotion.py index f84b8c1c..221f6e10 100644 --- a/indoteknik_api/controllers/api_v1/promotion.py +++ b/indoteknik_api/controllers/api_v1/promotion.py @@ -6,6 +6,28 @@ from datetime import datetime class Promotion(controller.Controller): prefix = '/api/v1/' + + @http.route(prefix + 'program-line//stock', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def get_promotion_stock(self, id): + program_line = request.env['promotion.program.line'].browse(int(id)) + if not program_line.id: + return self.response(code=400, description='program not found') + + user_data = self.verify_user_token() + + limit_qty = program_line._res_limit_qty() + remaining_qty = program_line._get_remaining_qty(user_data) + + percent_remaining = 0 + if limit_qty['all'] > 0: + percent_remaining = (limit_qty['all'] - remaining_qty['all']) / limit_qty['all'] * 100 + + return self.response({ + 'limit_qty': limit_qty, + 'remaining_qty': remaining_qty, + 'used_percentage': percent_remaining, + }) @http.route(prefix + 'promotion/', auth='public', methods=['GET']) -- cgit v1.2.3 From 6a87e59e7220bdfa78e98b23003ccc4ef41bd0ce Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 10 Oct 2023 10:42:30 +0700 Subject: Add program and program line constrains --- indoteknik_custom/models/solr/promotion_program.py | 7 +++++++ .../models/solr/promotion_program_line.py | 24 ++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/indoteknik_custom/models/solr/promotion_program.py b/indoteknik_custom/models/solr/promotion_program.py index c288c165..0d417b3e 100644 --- a/indoteknik_custom/models/solr/promotion_program.py +++ b/indoteknik_custom/models/solr/promotion_program.py @@ -59,3 +59,10 @@ class PromotionProgram(models.Model): def write(self, vals): self._create_solr_queue('_sync_to_solr') return super(PromotionProgram, self).write(vals) + + @api.constrains('program_line') + def constrains_program_line(self): + for rec in self: + for line in rec.program_line: + line._create_solr_queue('_sync_to_solr') + diff --git a/indoteknik_custom/models/solr/promotion_program_line.py b/indoteknik_custom/models/solr/promotion_program_line.py index e5f22e74..b0aeaa13 100644 --- a/indoteknik_custom/models/solr/promotion_program_line.py +++ b/indoteknik_custom/models/solr/promotion_program_line.py @@ -1,15 +1,16 @@ from odoo import models, api from typing import Type -import pysolr, json +import pysolr +import json class PromotionProgramLine(models.Model): _inherit = 'promotion.program.line' _solr_schema = 'promotion_program_lines' - + def solr(self) -> Type[pysolr.Solr]: return self.env['apache.solr'].connect(self._solr_schema) - + def _create_solr_queue(self, function_name: str): for rec in self: self.env['apache.solr.queue'].create_unique({ @@ -17,23 +18,23 @@ class PromotionProgramLine(models.Model): 'res_id': rec.id, 'function_name': function_name }) - + def _sync_to_solr(self): solr_model = self.env['apache.solr'] for rec in self: document = solr_model.get_doc(self._solr_schema, rec.id) - + products = [{ 'product_id': x.product_id.id, 'qty': x.qty } for x in rec.product_ids] - + free_products = [{ 'product_id': x.product_id.id, 'qty': x.qty } for x in rec.free_product_ids] - + document.update({ 'id': rec.id, 'program_id_i': rec.program_id.id, @@ -47,18 +48,19 @@ class PromotionProgramLine(models.Model): 'product_ids': [x.product_id.id for x in rec.product_ids], 'products_s': json.dumps(products), 'free_product_ids': [x.product_id.id for x in rec.free_product_ids], - 'free_products_s': json.dumps(free_products) + 'free_products_s': json.dumps(free_products), + 'total_qty_i': sum([x.qty for x in rec.product_ids] + [x.qty for x in rec.free_product_ids]), }) self.solr().add([document]) self.solr().commit() - + @api.model def create(self, vals): self._create_solr_queue('_sync_to_solr') return super(PromotionProgramLine, self).create(vals) - + def write(self, vals): self._create_solr_queue('_sync_to_solr') - return super(PromotionProgramLine, self).write(vals) \ No newline at end of file + return super(PromotionProgramLine, self).write(vals) -- cgit v1.2.3 From c1f7742c254898fa5981e8ca7d870ac42d3f8346 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Fri, 8 Dec 2023 14:58:52 +0700 Subject: Update document payload for promotion program lines SOLR --- indoteknik_custom/models/solr/promotion_program_line.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/solr/promotion_program_line.py b/indoteknik_custom/models/solr/promotion_program_line.py index b0aeaa13..6e182324 100644 --- a/indoteknik_custom/models/solr/promotion_program_line.py +++ b/indoteknik_custom/models/solr/promotion_program_line.py @@ -35,12 +35,15 @@ class PromotionProgramLine(models.Model): 'qty': x.qty } for x in rec.free_product_ids] + promotion_type = rec._res_promotion_type() + document.update({ 'id': rec.id, 'program_id_i': rec.program_id.id, 'name_s': rec.name, 'image_s': self.env['ir.attachment'].api_image(self._name, 'image', rec.id) if rec.image else '', - 'type_s': json.dumps(rec._res_promotion_type()), + 'type_value_s': promotion_type['value'], + 'type_label_s': promotion_type['label'], 'package_limit_i': rec.package_limit, 'package_limit_user_i': rec.package_limit_user, 'package_limit_trx_i': rec.package_limit_trx, -- cgit v1.2.3 From ad127a4dc2bfb81d9c99ba78ab41a49eefeb0dd2 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Fri, 22 Dec 2023 11:20:45 +0700 Subject: update promotion program feature --- indoteknik_api/controllers/api_v1/cart.py | 21 +++++++++++++++------ .../models/promotion/promotion_program_line.py | 7 ++++++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/cart.py b/indoteknik_api/controllers/api_v1/cart.py index 8ef2c1c1..907c8288 100644 --- a/indoteknik_api/controllers/api_v1/cart.py +++ b/indoteknik_api/controllers/api_v1/cart.py @@ -36,18 +36,21 @@ class Cart(controller.Controller): def create_or_update_cart(self, user_id, **kw): # Convert input values to appropriate types user_id = int(user_id) - product_id = int(kw.get('product_id', 0)) - qty = int(kw.get('qty', 0)) - source = kw.get('source') - is_selected = kw.get('selected', False) + product_id = kw.get('product_id', 0) + product_id = False if product_id == 'null' or not product_id else int(product_id) + program_line_id = kw.get('program_line_id', False) program_line_id = False if program_line_id == 'null' or not program_line_id else int(program_line_id) + qty = int(kw.get('qty', 0)) + source = kw.get('source') + + is_selected = kw.get('selected', False) is_selected = is_selected in ('true', True) # Check required fields - if not user_id or not product_id or not qty: - return self.response(code=400, description='user_id, product_id and qty is required') + if not user_id: + return self.response(code=400, description='user_id is required') website_user_cart = request.env['website.user.cart'] @@ -97,9 +100,15 @@ class Cart(controller.Controller): def delete_cart_by_user_id(self, user_id, **kw): user_id = int(user_id) query = [('user_id', '=', user_id)] + + ids = kw.get('ids') + if ids: + query += [('id', 'in', [int(x) for x in ids.split(',')])] + product_ids = kw.get('product_ids') if product_ids: query += [('product_id', 'in', [int(x) for x in product_ids.split(',')])] + cart = request.env['website.user.cart'].search(query).unlink() return self.response(cart) diff --git a/indoteknik_custom/models/promotion/promotion_program_line.py b/indoteknik_custom/models/promotion/promotion_program_line.py index 34a0fbb2..d9095c75 100644 --- a/indoteknik_custom/models/promotion/promotion_program_line.py +++ b/indoteknik_custom/models/promotion/promotion_program_line.py @@ -96,7 +96,11 @@ class PromotionProgramLine(models.Model): weight = 0 if not any(x['package_weight'] == 0 for x in merged_products): weight = sum(x['package_weight'] for x in merged_products) - + + products_total = sum(x['price']['price_discount'] * x['qty'] for x in products) + free_products_total = sum(x['price']['price_discount'] * x['qty'] for x in free_products) + package_price = products_total + free_products_total + response = { 'id': self.id, 'name': self.name, @@ -106,6 +110,7 @@ class PromotionProgramLine(models.Model): 'limit_qty': limit_qty, 'remaining_qty': remaining_qty, 'used_percentage': percent_remaining, + 'package_price': package_price, 'price': { 'price': self.price, 'price_discount': self.price, -- cgit v1.2.3 From c6dbde248d5a9c12f7e1f53ce4596f6b5611750a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 22 Dec 2023 14:31:37 +0700 Subject: fix suggest po --- indoteknik_custom/models/purchase_order_line.py | 15 +++++++++++++-- indoteknik_custom/models/sale_order_line.py | 14 +++++++++++++- indoteknik_custom/views/purchase_order.xml | 4 +++- indoteknik_custom/views/sale_order.xml | 3 +++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index ca0e77ab..9406f85f 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -33,10 +33,21 @@ class PurchaseOrderLine(models.Model): indent = fields.Boolean(string='Indent', help='centang ini jika barang indent') is_ltc = fields.Boolean(string='Sudah di LTC', default=False, help='centang ini jika barang sudah di LTC') note = fields.Char(string='Note') + qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') + + def _compute_qty_reserved(self): + for line in self: + sale_line = self.env['sale.order.line'].search([ + ('product_id', '=', line.product_id.id), + ('order_id', '=', line.order_id.sale_order_id.id) + ]) + + reserved_qty = sum(line.qty_reserved for line in sale_line) + line.qty_reserved = reserved_qty def suggest_purchasing(self): - for line in self: - if line.qty_available < line.product_qty: + for line in self: + if line.product_id.qty_available_bandengan + line.qty_reserved < line.product_qty: line.suggest = 'harus beli' else: line.suggest = 'masih cukup' diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index eda003c7..358cbfe2 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -27,7 +27,19 @@ class SaleOrderLine(models.Model): 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') + + def _compute_qty_reserved(self): + for line in self: + stock_moves = self.env['stock.move.line'].search([ + ('product_id', '=', line.product_id.id), + ('picking_id.sale_id', '=', line.order_id.id), + ('picking_id.state', 'not in', ['cancel', 'done']), + ]) + + reserved_qty = sum(move.product_uom_qty for move in stock_moves) + line.qty_reserved = reserved_qty + def _compute_vendor_subtotal(self): for line in self: if line.purchase_price > 0 and line.product_uom_qty > 0: diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 8e74df4a..21e8c328 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -55,7 +55,9 @@ - + + + diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 5db2f1e1..18ae4c51 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -105,6 +105,9 @@ + + + {'no_create': True} -- cgit v1.2.3 From 08724b92174a216a64b382012e83e45c16b326e7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 28 Dec 2023 13:23:49 +0700 Subject: add validation on sale order Tempo 3 months must be margin 25 --- indoteknik_custom/models/sale_order.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 1b51f44b..12526131 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1,5 +1,5 @@ from odoo import fields, models, api, _ -from odoo.exceptions import UserError +from odoo.exceptions import UserError, ValidationError from datetime import datetime import logging, random, string, requests, math, json, re @@ -365,10 +365,15 @@ class SaleOrder(models.Model): order.is_warning = False def _validate_order(self): + if self.payment_term_id.id == 31 and self.total_percent_margin < 25: + raise UserError("Total Margin Belum mencapai 25%") + if self.warehouse_id.id != 8: #GD Bandengan raise UserError('Gudang harus Bandengan') + if self.state not in ['draft', 'sent']: raise UserError("Status harus draft atau sent") + if not self._validate_npwp(): raise UserError("Isi NPWP Dengan Benar!") @@ -379,8 +384,8 @@ class SaleOrder(models.Model): def sale_order_approve(self): self.check_due() + self._validate_order() for order in self: - order._validate_order() order.order_line.validate_line() partner = order.partner_id.parent_id or order.partner_id -- cgit v1.2.3 From 5446eefa619906ba785d1f867fd828cce0d0748c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 29 Dec 2023 13:44:00 +0700 Subject: multi update paid status on po --- indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/purchase_order.py | 13 +++++++++ .../models/purchase_order_multi_update.py | 22 +++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 3 ++- indoteknik_custom/views/purchase_order.xml | 9 +++++++ .../views/purchase_order_multi_update.xml | 31 ++++++++++++++++++++++ 7 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/purchase_order_multi_update.py create mode 100644 indoteknik_custom/views/purchase_order_multi_update.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 39e5cdd9..d8058bff 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -104,6 +104,7 @@ 'views/stock_warehouse_orderpoint.xml', 'views/customer_commision.xml', 'views/wati_history.xml', + 'views/purchase_order_multi_update.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 50885f56..c6f61ffa 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -94,3 +94,4 @@ from . import account_bank_statement from . import stock_warehouse_orderpoint from . import commision from . import sale_advance_payment_inv +from . import purchase_order_multi_update diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 285c5a95..6641e204 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -52,6 +52,19 @@ class PurchaseOrder(models.Model): responsible_ids = fields.Many2many('res.users', string='Responsibles', compute='_compute_responsibles') status_paid_cbd = fields.Boolean(string='Paid Status', tracking=3, help='Field ini diisi secara manual oleh Finance AP dan hanya untuk status PO CBD') + def action_multi_update_paid_status(self): + for purchase in self: + purchase.update({ + 'status_paid_cbd': True, + }) + + def open_form_multi_update_paid_status(self): + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_purchase_order_multi_update') + action['context'] = { + 'purchase_ids': [x.id for x in self] + } + return action + def _compute_responsibles(self): for purchase in self: resposible_ids = [] diff --git a/indoteknik_custom/models/purchase_order_multi_update.py b/indoteknik_custom/models/purchase_order_multi_update.py new file mode 100644 index 00000000..aab46de8 --- /dev/null +++ b/indoteknik_custom/models/purchase_order_multi_update.py @@ -0,0 +1,22 @@ +from odoo import models, fields +import logging + +_logger = logging.getLogger(__name__) + + +class PurchaseOrderMultiUpdate(models.TransientModel): + _name = 'purchase.order.multi_update' + + def save_multi_update_paid_status(self): + purchase_ids = self._context['purchase_ids'] + purchase = self.env['purchase.order'].browse(purchase_ids) + purchase.action_multi_update_paid_status() + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Notification', + 'message': 'Paid Status berhasil diubah', + 'next': {'type': 'ir.actions.act_window_close'}, + } + } \ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 444a1b42..dd7605ab 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -84,4 +84,5 @@ access_customer_commision_line,access.customer.commision.line,model_customer_com access_customer_rebate,access.customer.rebate,model_customer_rebate,,1,1,1,1 access_wati_history,access.wati.history,model_wati_history,,1,1,1,1 access_wati_history_line,access.wati.history.line,model_wati_history_line,,1,1,1,1 -access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advance_payment_inv,,1,1,1,1 \ No newline at end of file +access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advance_payment_inv,,1,1,1,1 +access_purchase_order_multi_update,access.purchase.order.multi_update,model_purchase_order_multi_update,,1,1,1,1 \ No newline at end of file diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 21e8c328..3a95393e 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -188,4 +188,13 @@ + + + Update Paid Status + + + code + action = records.open_form_multi_update_paid_status() + + \ No newline at end of file diff --git a/indoteknik_custom/views/purchase_order_multi_update.xml b/indoteknik_custom/views/purchase_order_multi_update.xml new file mode 100644 index 00000000..7cfcd64d --- /dev/null +++ b/indoteknik_custom/views/purchase_order_multi_update.xml @@ -0,0 +1,31 @@ + + + + + Purchase Order Multi Update Paid Status + purchase.order.multi_update + +
+ + + Apakah Anda Yakin Ingin Mengubah Paid Status? + + +
+
+
+
+
+ + + Purchase Order Multi Update Paid Status + purchase.order.multi_update + ir.actions.act_window + form + + new + +
+
\ No newline at end of file -- cgit v1.2.3 From 0ecd24dd099295d664c3e80f064e8276395a8f89 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 2 Jan 2024 08:56:20 +0700 Subject: change message validation on purchase pricelist and sale order --- indoteknik_custom/models/purchase_pricelist.py | 2 +- indoteknik_custom/models/sale_order.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index b7c3785a..86bb2f54 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -39,8 +39,8 @@ class PurchasePricelist(models.Model): ] domain.append(('id', '!=', price.id)) - massage="Product dan vendor yang anda gunakan sudah ada di purchase pricelist" existing_purchase = self.search(domain, limit=1) + massage="Ada duplikat product dan vendor, berikut data yang anda duplikat : \n" + str(existing_purchase.product_id.name) + " - " + str(existing_purchase.vendor_id.name) + " - " + str(existing_purchase.product_price) if existing_purchase: raise UserError(massage) \ No newline at end of file diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 12526131..07c37fe7 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -366,7 +366,7 @@ class SaleOrder(models.Model): def _validate_order(self): if self.payment_term_id.id == 31 and self.total_percent_margin < 25: - raise UserError("Total Margin Belum mencapai 25%") + raise UserError("Jika ingin menggunakan Tempo 90 Hari maka margin harus di atas 25%") if self.warehouse_id.id != 8: #GD Bandengan raise UserError('Gudang harus Bandengan') -- cgit v1.2.3 From 13b31fc3d89957d23582efb2c51ab143ca1d425a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 3 Jan 2024 10:28:53 +0700 Subject: logic regex email --- indoteknik_custom/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 07c37fe7..ad27c64c 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -129,7 +129,7 @@ class SaleOrder(models.Model): pattern = rf'^{rule_regex}$' if self.email and not re.match(pattern, self.email): - raise UserError('Email harus menggunakan karakter @') + raise UserError('Email yang anda input kurang valid') def override_allow_create_invoice(self): if not self.env.user.is_accounting: -- cgit v1.2.3 From 717cb3b43c729e265603b3df61234c0b430742a7 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 4 Jan 2024 09:25:14 +0700 Subject: update promotion program feature --- .../models/promotion/promotion_program.py | 1 + .../models/promotion/promotion_program_line.py | 9 ++++----- indoteknik_custom/models/website_user_cart.py | 20 +++++++++++++++++--- .../views/promotion/promotion_program.xml | 1 + .../views/promotion/promotion_program_line.xml | 1 - 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/indoteknik_custom/models/promotion/promotion_program.py b/indoteknik_custom/models/promotion/promotion_program.py index 29aaa753..1a1ee6bf 100644 --- a/indoteknik_custom/models/promotion/promotion_program.py +++ b/indoteknik_custom/models/promotion/promotion_program.py @@ -6,6 +6,7 @@ class PromotionProgram(models.Model): name = fields.Char(string="Name") banner = fields.Binary(string="Banner") + image = fields.Binary(string="Image") icon = fields.Binary(string="Icon", help="Image 1:1 ratio") icon_top = fields.Binary(string="Icon Top", help="Icon ini ditampilkan sebagai atribut pada atas gambar di product card pada website") icon_bottom = fields.Binary(string="Icon Bottom", help="Icon ini ditampilkan sebagai atribut pada bawah gambar di product card pada website") diff --git a/indoteknik_custom/models/promotion/promotion_program_line.py b/indoteknik_custom/models/promotion/promotion_program_line.py index d9095c75..d77123ce 100644 --- a/indoteknik_custom/models/promotion/promotion_program_line.py +++ b/indoteknik_custom/models/promotion/promotion_program_line.py @@ -13,7 +13,6 @@ class PromotionProgramLine(models.Model): ("discount_loading", "Discount Loading"), ("merchandise", "Merchandise") ], 'Type') - image = fields.Binary(string="Image") package_limit = fields.Integer('Package limit') package_limit_user = fields.Integer('Package limit / user') @@ -96,15 +95,15 @@ class PromotionProgramLine(models.Model): weight = 0 if not any(x['package_weight'] == 0 for x in merged_products): weight = sum(x['package_weight'] for x in merged_products) - - products_total = sum(x['price']['price_discount'] * x['qty'] for x in products) - free_products_total = sum(x['price']['price_discount'] * x['qty'] for x in free_products) + + # Sum of products and free products in 1 package quantity + products_total = sum(x['price']['price_discount'] * x['qty'] / qty for x in products) + free_products_total = sum(x['price']['price_discount'] * x['qty'] / qty for x in free_products) package_price = products_total + free_products_total response = { 'id': self.id, 'name': self.name, - 'image': ir_attachment.api_image(self._name, 'image', self.id), 'remaining_time': self._get_remaining_time(), 'promotion_type': self._res_promotion_type(), 'limit_qty': limit_qty, diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index bbc14c88..eaa5f009 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -51,7 +51,9 @@ class WebsiteUserCart(models.Model): return res def get_products(self): - return [x.get_product() for x in self] + products = [x.get_product() for x in self] + + return products def get_product_by_user(self, user_id, selected=False, source=False): user_id = int(user_id) @@ -75,8 +77,20 @@ class WebsiteUserCart(models.Model): def get_user_checkout(self, user_id, voucher=False, source=False): products = self.get_product_by_user(user_id=user_id, selected=True, source=source) - total_purchase = sum(x['price']['price'] * x['quantity'] for x in products) - total_discount = sum((x['price']['price'] - x['price']['price_discount']) * x['quantity'] for x in products) + + total_purchase = 0 + total_discount = 0 + for product in products: + if product['cart_type'] == 'promotion': + price = product['package_price'] * product['quantity'] + else: + price = product['price']['price'] * product['quantity'] + + discount_price = price - product['price']['price_discount'] * product['quantity'] + + total_purchase += price + total_discount += discount_price + subtotal = total_purchase - total_discount discount_voucher = 0 if voucher: diff --git a/indoteknik_custom/views/promotion/promotion_program.xml b/indoteknik_custom/views/promotion/promotion_program.xml index f8432d8a..724f80c7 100644 --- a/indoteknik_custom/views/promotion/promotion_program.xml +++ b/indoteknik_custom/views/promotion/promotion_program.xml @@ -22,6 +22,7 @@ + diff --git a/indoteknik_custom/views/promotion/promotion_program_line.xml b/indoteknik_custom/views/promotion/promotion_program_line.xml index db6d5252..346a08c9 100644 --- a/indoteknik_custom/views/promotion/promotion_program_line.xml +++ b/indoteknik_custom/views/promotion/promotion_program_line.xml @@ -23,7 +23,6 @@ - -- cgit v1.2.3 From 4b89fcf620a93aab85c2eb81526afee1c355e14e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 4 Jan 2024 11:18:21 +0700 Subject: replenishment error --- indoteknik_custom/models/stock_warehouse_orderpoint.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indoteknik_custom/models/stock_warehouse_orderpoint.py b/indoteknik_custom/models/stock_warehouse_orderpoint.py index 277c8dc3..26427c2b 100644 --- a/indoteknik_custom/models/stock_warehouse_orderpoint.py +++ b/indoteknik_custom/models/stock_warehouse_orderpoint.py @@ -8,3 +8,6 @@ class StockWarehouseOrderpoint(models.Model): def _compute_responsible(self): for stock in self: stock.responsible_id = stock.product_id.x_manufacture.user_id + + def _get_orderpoint_action(self): + return \ No newline at end of file -- cgit v1.2.3 From f4217b5493477d8238165f9390dd6c6f8a597b33 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 6 Jan 2024 09:11:00 +0700 Subject: change regex on function validate_npwp --- indoteknik_custom/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ad27c64c..d75c9fe9 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -378,7 +378,7 @@ class SaleOrder(models.Model): raise UserError("Isi NPWP Dengan Benar!") def _validate_npwp(self): - pattern = r'^\d{2}\.\d{3}\.\d{3}\.\d{1}-\d{3}\.\d{3}$' + pattern = r'^\d{16,}$' return re.match(pattern, self.npwp) is not None def sale_order_approve(self): -- cgit v1.2.3 From 1fe227b2fcbbc31b8766aa3e1ddf3997d535a823 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Sat, 6 Jan 2024 10:41:43 +0700 Subject: temporary comment npwp --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d75c9fe9..a99e15ad 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -374,8 +374,8 @@ class SaleOrder(models.Model): if self.state not in ['draft', 'sent']: raise UserError("Status harus draft atau sent") - if not self._validate_npwp(): - raise UserError("Isi NPWP Dengan Benar!") + # if not self._validate_npwp(): + # raise UserError("Isi NPWP Dengan Benar!") def _validate_npwp(self): pattern = r'^\d{16,}$' -- cgit v1.2.3 From 89d4e9c8df4babbaa8daccdf4a6f77fee8a06123 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 6 Jan 2024 13:12:07 +0700 Subject: change validation npwp on sale order --- indoteknik_custom/models/sale_order.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d75c9fe9..cb963122 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -374,12 +374,16 @@ class SaleOrder(models.Model): if self.state not in ['draft', 'sent']: raise UserError("Status harus draft atau sent") - if not self._validate_npwp(): - raise UserError("Isi NPWP Dengan Benar!") + self._validate_npwp() def _validate_npwp(self): - pattern = r'^\d{16,}$' - return re.match(pattern, self.npwp) is not None + num_digits = sum(c.isdigit() for c in self.npwp) + + if num_digits <= 10: + raise UserError("NPWP harus memiliki minimal 10 digit") + + # pattern = r'^\d{10,}$' + # return re.match(pattern, self.npwp) is not None def sale_order_approve(self): self.check_due() -- cgit v1.2.3 From 38b28cfb316a1abf62f192ce03f938c70f21f1fb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Sat, 6 Jan 2024 13:12:51 +0700 Subject: multiple reklas --- indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/account_move.py | 17 +++++ indoteknik_custom/models/invoice_reklas.py | 48 +++++++++++++ .../models/invoice_reklas_penjualan.py | 79 ++++++++++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 4 +- indoteknik_custom/views/account_move.xml | 9 +++ .../views/invoice_reklas_penjualan.xml | 39 +++++++++++ 8 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/invoice_reklas_penjualan.py create mode 100644 indoteknik_custom/views/invoice_reklas_penjualan.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index d8058bff..d6e69718 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -105,6 +105,7 @@ 'views/customer_commision.xml', 'views/wati_history.xml', 'views/purchase_order_multi_update.xml', + 'views/invoice_reklas_penjualan.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index e7bcd323..509fceef 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -95,3 +95,4 @@ from . import stock_warehouse_orderpoint from . import commision from . import sale_advance_payment_inv from . import purchase_order_multi_update +from . import invoice_reklas_penjualan diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 82a86a39..929d2ee6 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -35,6 +35,23 @@ class AccountMove(models.Model): ('belum_upload', 'Belum Upload FP'), ('sudah_upload', 'Sudah Upload FP'), ], 'Mark Upload Faktur', compute='_compute_mark_upload_efaktur', default='belum_upload') + reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('partner_id', '=', partner_id)]") + + def open_form_multi_create_reklas_penjualan(self): + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_view_invoice_reklas_penjualan') + invoice = self.env['invoice.reklas.penjualan'].create([{ + 'name': '-', + }]) + for move in self: + self.env['invoice.reklas.penjualan.line'].create([{ + 'invoice_reklas_id': invoice.id, + 'name': move.name, + 'partner_id': move.partner_id.id, + 'amount_untaxed_signed': move.amount_untaxed_signed, + 'amount_total_signed': move.amount_total_signed, + }]) + action['res_id'] = invoice.id + return action def _compute_mark_upload_efaktur(self): for move in self: diff --git a/indoteknik_custom/models/invoice_reklas.py b/indoteknik_custom/models/invoice_reklas.py index c2ee7e3d..b1ba49e8 100644 --- a/indoteknik_custom/models/invoice_reklas.py +++ b/indoteknik_custom/models/invoice_reklas.py @@ -94,3 +94,51 @@ class InvoiceReklas(models.TransientModel): 'type': 'ir.actions.act_window', 'res_id': account_move.id } + + + def create_reklas_penjualan(self): + if not self.pay_amt: + raise UserError('Yang dibayarkan harus diisi') + + account_ids = self._context['account_ids'] + invoices = self.env['account.move'].browse(account_ids) + current_time = datetime.now() + for invoice in invoices: + ref_name = 'REKLAS '+invoice.reklas_id.name+" UANG MUKA PENJUALAN "+invoice.name+" "+invoice.partner_id.name + parameters_header = { + 'ref': ref_name, + 'date': current_time, + 'journal_id': 13 + } + + account_move = request.env['account.move'].create([parameters_header]) + _logger.info('Success Reklas with %s' % account_move.name) + + parameter_debit = { + 'move_id': account_move.id, + 'account_id': 449, # uang muka penjualan + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': self.pay_amt, + 'credit': 0, + 'name': ref_name + } + parameter_credit = { + 'move_id': account_move.id, + 'account_id': 395, + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': 0, + 'credit': self.pay_amt, + 'name': ref_name + } + request.env['account.move.line'].create([parameter_debit, parameter_credit]) + return { + 'name': _('Journal Entries'), + 'view_mode': 'form', + 'res_model': 'account.move', + 'target': 'current', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'res_id': account_move.id + } diff --git a/indoteknik_custom/models/invoice_reklas_penjualan.py b/indoteknik_custom/models/invoice_reklas_penjualan.py new file mode 100644 index 00000000..22417864 --- /dev/null +++ b/indoteknik_custom/models/invoice_reklas_penjualan.py @@ -0,0 +1,79 @@ +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from datetime import datetime +from odoo.http import request + +import logging + +_logger = logging.getLogger(__name__) + + +class InvoiceReklasPenjualan(models.TransientModel): + _name = 'invoice.reklas.penjualan' + _description = "digunakan untuk reklas Uang Muka Penjualan" + + name = fields.Char(string='Name') + invoice_reklas_line = fields.One2many('invoice.reklas.penjualan.line', 'invoice_reklas_id', string='Invoice Reklas Line') + + def create_reklas_penjualan(self): + # invoices = self.invoice_reklas_line.mapped('invoice_id') + invoices = self.invoice_reklas_line + + current_time = datetime.now() + account_move_ids = [] + for invoice in invoices: + ref_name = 'REKLAS ' + invoice.reklas_id.name + " UANG MUKA PENJUALAN " + invoice.name + " " + invoice.partner_id.name + parameters_header = { + 'ref': ref_name, + 'date': current_time, + 'journal_id': 13 + } + + account_move = self.env['account.move'].create([parameters_header]) + _logger.info('Success Reklas with %s' % account_move.name) + + parameter_debit = { + 'move_id': account_move.id, + 'account_id': 449, # uang muka penjualan + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': invoice.pay_amt, + 'credit': 0, + 'name': ref_name + } + parameter_credit = { + 'move_id': account_move.id, + 'account_id': 395, + 'partner_id': invoice.partner_id.id, + 'currency_id': 12, + 'debit': 0, + 'credit': invoice.pay_amt, + 'name': ref_name + } + self.env['account.move.line'].create([parameter_debit, parameter_credit]) + account_move_ids.append(account_move.id) + invoice.unlink() + + self.unlink() + return { + 'name': _('Journal Entries'), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', account_move_ids)], + } + +class InvoiceReklasPenjualanLine(models.TransientModel): + _name = 'invoice.reklas.penjualan.line' + _description = "digunakan untuk reklas Uang Muka Penjualan" + + invoice_reklas_id = fields.Many2one('invoice.reklas.penjualan', string='Invoice Reklas') + pay_amt = fields.Float(string='Yang dibayarkan') + reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('partner_id', '=', partner_id)]") + amount_untaxed_signed = fields.Float(string='Tax excluded') + amount_total_signed = fields.Float(string='Total') + name = fields.Char(string='Name') + partner_id = fields.Many2one('res.partner', string='Partner') + + diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index dd7605ab..8520961d 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -85,4 +85,6 @@ access_customer_rebate,access.customer.rebate,model_customer_rebate,,1,1,1,1 access_wati_history,access.wati.history,model_wati_history,,1,1,1,1 access_wati_history_line,access.wati.history.line,model_wati_history_line,,1,1,1,1 access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advance_payment_inv,,1,1,1,1 -access_purchase_order_multi_update,access.purchase.order.multi_update,model_purchase_order_multi_update,,1,1,1,1 \ No newline at end of file +access_purchase_order_multi_update,access.purchase.order.multi_update,model_purchase_order_multi_update,,1,1,1,1 +access_invoice_reklas_penjualan,access.invoice.reklas.penjualan,model_invoice_reklas_penjualan,,1,1,1,1 +access_invoice_reklas_penjualan_line,access.invoice.reklas.penjualan.line,model_invoice_reklas_penjualan_line,,1,1,1,1 \ No newline at end of file diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 7995b83b..97ac5460 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -15,6 +15,7 @@ + @@ -108,5 +109,13 @@ code action = records.open_form_multi_update() + + + Create Reklas Penjualan + + + code + action = records.open_form_multi_create_reklas_penjualan() + \ No newline at end of file diff --git a/indoteknik_custom/views/invoice_reklas_penjualan.xml b/indoteknik_custom/views/invoice_reklas_penjualan.xml new file mode 100644 index 00000000..ba892633 --- /dev/null +++ b/indoteknik_custom/views/invoice_reklas_penjualan.xml @@ -0,0 +1,39 @@ + + + + Invoice Reklas Penjualan + invoice.reklas.penjualan + +
+ + + + + + + + + + + + + +
+
+
+
+
+ + + Create Reklas Penjualan + ir.actions.act_window + invoice.reklas.penjualan + form + new + +
-- cgit v1.2.3 From e5474a12a7d3b0d8c1a73d5e072078e6be745196 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 8 Jan 2024 11:39:54 +0700 Subject: multiple-reklas --- indoteknik_custom/models/account_move.py | 1 + indoteknik_custom/models/sale_advance_payment_inv.py | 1 + indoteknik_custom/models/sale_order.py | 2 +- indoteknik_custom/models/uangmuka_penjualan.py | 3 ++- indoteknik_custom/views/account_move.xml | 7 +++++++ 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 929d2ee6..47eb90f8 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -35,6 +35,7 @@ class AccountMove(models.Model): ('belum_upload', 'Belum Upload FP'), ('sudah_upload', 'Sudah Upload FP'), ], 'Mark Upload Faktur', compute='_compute_mark_upload_efaktur', default='belum_upload') + sale_id = fields.Many2one('sale.order', string='Sale Order') reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('partner_id', '=', partner_id)]") def open_form_multi_create_reklas_penjualan(self): diff --git a/indoteknik_custom/models/sale_advance_payment_inv.py b/indoteknik_custom/models/sale_advance_payment_inv.py index dde7ed74..ebbba6b9 100644 --- a/indoteknik_custom/models/sale_advance_payment_inv.py +++ b/indoteknik_custom/models/sale_advance_payment_inv.py @@ -16,6 +16,7 @@ class SaleAdvancePaymentInv(models.TransientModel): 'invoice_user_id': order.user_id.id, 'narration': order.note, 'partner_id': parent_id, + 'sale_id': order.id, 'fiscal_position_id': (order.fiscal_position_id or order.fiscal_position_id.get_fiscal_position(order.partner_id.id)).id, 'partner_shipping_id': parent_id.id, 'currency_id': order.pricelist_id.currency_id.id, diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index cb963122..95cbf8ce 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -379,7 +379,7 @@ class SaleOrder(models.Model): def _validate_npwp(self): num_digits = sum(c.isdigit() for c in self.npwp) - if num_digits <= 10: + if num_digits < 10: raise UserError("NPWP harus memiliki minimal 10 digit") # pattern = r'^\d{10,}$' diff --git a/indoteknik_custom/models/uangmuka_penjualan.py b/indoteknik_custom/models/uangmuka_penjualan.py index 93a33b52..65f5361b 100644 --- a/indoteknik_custom/models/uangmuka_penjualan.py +++ b/indoteknik_custom/models/uangmuka_penjualan.py @@ -48,7 +48,8 @@ class UangmukaPenjualan(models.TransientModel): param_header = { 'ref': ref_label, 'date': current_time, - 'journal_id': 11 + 'journal_id': 11, + 'sale_id': order.id, } account_move = request.env['account.move'].create([param_header]) diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 97ac5460..ddd266bb 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -17,6 +17,12 @@ + + + + + + @@ -24,6 +30,7 @@ pdf_viewer + -- cgit v1.2.3 From 7622354cbe00ca428d94469c6bd5ae3de5e73a76 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 8 Jan 2024 13:26:16 +0700 Subject: multiple invoice reklas penjualan --- indoteknik_custom/models/account_move.py | 2 ++ indoteknik_custom/models/invoice_reklas_penjualan.py | 3 ++- indoteknik_custom/views/invoice_reklas_penjualan.xml | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 47eb90f8..ae09d0ee 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -44,10 +44,12 @@ class AccountMove(models.Model): 'name': '-', }]) for move in self: + sale_id = move.sale_id.id self.env['invoice.reklas.penjualan.line'].create([{ 'invoice_reklas_id': invoice.id, 'name': move.name, 'partner_id': move.partner_id.id, + 'sale_id': move.sale_id.id, 'amount_untaxed_signed': move.amount_untaxed_signed, 'amount_total_signed': move.amount_total_signed, }]) diff --git a/indoteknik_custom/models/invoice_reklas_penjualan.py b/indoteknik_custom/models/invoice_reklas_penjualan.py index 22417864..533270d2 100644 --- a/indoteknik_custom/models/invoice_reklas_penjualan.py +++ b/indoteknik_custom/models/invoice_reklas_penjualan.py @@ -70,7 +70,8 @@ class InvoiceReklasPenjualanLine(models.TransientModel): invoice_reklas_id = fields.Many2one('invoice.reklas.penjualan', string='Invoice Reklas') pay_amt = fields.Float(string='Yang dibayarkan') - reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('partner_id', '=', partner_id)]") + reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('sale_id', '=', sale_id)]") + sale_id = fields.Many2one('sale.order', string='Sale Order') amount_untaxed_signed = fields.Float(string='Tax excluded') amount_total_signed = fields.Float(string='Total') name = fields.Char(string='Name') diff --git a/indoteknik_custom/views/invoice_reklas_penjualan.xml b/indoteknik_custom/views/invoice_reklas_penjualan.xml index ba892633..9c875cca 100644 --- a/indoteknik_custom/views/invoice_reklas_penjualan.xml +++ b/indoteknik_custom/views/invoice_reklas_penjualan.xml @@ -17,6 +17,7 @@ + -- cgit v1.2.3 From 8be31f0f44c2fde870c7c85e27379f88e1b38d7c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 9 Jan 2024 13:37:37 +0700 Subject: delete function create_reklas_penjualan --- indoteknik_custom/models/invoice_reklas.py | 49 +--------------------- .../models/invoice_reklas_penjualan.py | 1 - 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/indoteknik_custom/models/invoice_reklas.py b/indoteknik_custom/models/invoice_reklas.py index b1ba49e8..30da02d1 100644 --- a/indoteknik_custom/models/invoice_reklas.py +++ b/indoteknik_custom/models/invoice_reklas.py @@ -94,51 +94,4 @@ class InvoiceReklas(models.TransientModel): 'type': 'ir.actions.act_window', 'res_id': account_move.id } - - - def create_reklas_penjualan(self): - if not self.pay_amt: - raise UserError('Yang dibayarkan harus diisi') - - account_ids = self._context['account_ids'] - invoices = self.env['account.move'].browse(account_ids) - current_time = datetime.now() - for invoice in invoices: - ref_name = 'REKLAS '+invoice.reklas_id.name+" UANG MUKA PENJUALAN "+invoice.name+" "+invoice.partner_id.name - parameters_header = { - 'ref': ref_name, - 'date': current_time, - 'journal_id': 13 - } - - account_move = request.env['account.move'].create([parameters_header]) - _logger.info('Success Reklas with %s' % account_move.name) - - parameter_debit = { - 'move_id': account_move.id, - 'account_id': 449, # uang muka penjualan - 'partner_id': invoice.partner_id.id, - 'currency_id': 12, - 'debit': self.pay_amt, - 'credit': 0, - 'name': ref_name - } - parameter_credit = { - 'move_id': account_move.id, - 'account_id': 395, - 'partner_id': invoice.partner_id.id, - 'currency_id': 12, - 'debit': 0, - 'credit': self.pay_amt, - 'name': ref_name - } - request.env['account.move.line'].create([parameter_debit, parameter_credit]) - return { - 'name': _('Journal Entries'), - 'view_mode': 'form', - 'res_model': 'account.move', - 'target': 'current', - 'view_id': False, - 'type': 'ir.actions.act_window', - 'res_id': account_move.id - } + \ No newline at end of file diff --git a/indoteknik_custom/models/invoice_reklas_penjualan.py b/indoteknik_custom/models/invoice_reklas_penjualan.py index 533270d2..5027c8af 100644 --- a/indoteknik_custom/models/invoice_reklas_penjualan.py +++ b/indoteknik_custom/models/invoice_reklas_penjualan.py @@ -16,7 +16,6 @@ class InvoiceReklasPenjualan(models.TransientModel): invoice_reklas_line = fields.One2many('invoice.reklas.penjualan.line', 'invoice_reklas_id', string='Invoice Reklas Line') def create_reklas_penjualan(self): - # invoices = self.invoice_reklas_line.mapped('invoice_id') invoices = self.invoice_reklas_line current_time = datetime.now() -- cgit v1.2.3 From 3615748eafd2d2cfd81f6ddc95d50a7bc347798d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 9 Jan 2024 14:11:04 +0700 Subject: ETA on sales dan purchase order --- indoteknik_custom/models/purchase_order.py | 14 +++++++++++--- indoteknik_custom/models/res_partner.py | 1 + indoteknik_custom/models/sale_order.py | 25 +++++++++++++++++++++++-- indoteknik_custom/views/res_partner.xml | 3 +++ indoteknik_custom/views/sale_order.xml | 3 +++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 6641e204..ba6b6c41 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -45,7 +45,7 @@ class PurchaseOrder(models.Model): summary_qty_po = fields.Float('Total Qty', compute='_compute_summary_qty') summary_qty_receipt = fields.Float('Summary Qty Receipt', compute='_compute_summary_qty') count_line_product = fields.Float('Total Item', compute='compute_count_line_product') - note_description = fields.Char(string='Note', help='bisa diisi sebagai informasi indent barang tertentu atau apapun') + note_description = fields.Char(string='Noteman', help='bisa diisi sebagai informasi indent barang tertentu atau apapun') has_active_invoice = fields.Boolean(string='Has Active Invoice', compute='_compute_has_active_invoice') description = fields.Char(string='Description', help='bisa diisi sebagai informasi indent barang tertentu atau apapun') purchase_order_lines = fields.One2many('purchase.order.line', 'order_id', string='Indent', auto_join=True) @@ -114,8 +114,9 @@ class PurchaseOrder(models.Model): def _compute_date_planned(self): for order in self: if order.date_approve: + leadtime = order.partner_id.leadtime current_time = order.date_approve - delta_time = current_time + timedelta(days=2) + delta_time = current_time + timedelta(days=leadtime) delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') order.date_planned = delta_time else: @@ -261,6 +262,11 @@ class PurchaseOrder(models.Model): amount += line.price_total order.delivery_amount = amount + def date_deadline_ref_date_planned(self): + for picking in self.picking_ids: + picking.scheduled_date = self.date_planned + picking.date_deadline = self.date_planned + def button_confirm(self): res = super(PurchaseOrder, self).button_confirm() @@ -287,10 +293,12 @@ class PurchaseOrder(models.Model): self.calculate_line_no() # override date planned added with two days + leadtime = self.partner_id.leadtime current_time = datetime.now() - delta_time = current_time + timedelta(days=2) + delta_time = current_time + timedelta(days=leadtime) delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') self.date_planned = delta_time + self.date_deadline_ref_date_planned() return res diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index fcde9369..a7302245 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -19,6 +19,7 @@ class ResPartner(models.Model): ]) sppkp = fields.Char(string="SPPKP") counter = fields.Integer(string="Counter", default=0) + leadtime = fields.Integer(string="Leadtime", default=0) digital_invoice_tax = fields.Boolean(string="Digital Invoice & Faktur Pajak") is_potential = fields.Boolean(string='Potential') pakta_integritas = fields.Boolean(string='Pakta Integritas') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 95cbf8ce..07fd60fc 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -1,6 +1,6 @@ from odoo import fields, models, api, _ from odoo.exceptions import UserError, ValidationError -from datetime import datetime +from datetime import datetime, timedelta import logging, random, string, requests, math, json, re _logger = logging.getLogger(__name__) @@ -82,7 +82,28 @@ class SaleOrder(models.Model): email = fields.Char(string='Email') picking_iu_id = fields.Many2one('stock.picking', 'Picking IU') helper_by_id = fields.Many2one('res.users', 'Helper By') - # picking_ids = fields.Many2many('stock.picking', string='Pickings', compute='_get_pickings', readonly=True, copy=False, search="_search_picking_ids") + eta_date = fields.Datetime(string='ETA Date', tracking=3, copy=False, compute='_compute_eta_date') + + def _compute_eta_date(self): + unique_partner_ids = set() + total_leadtime = 0 + total_orders = 0 + + for line in self.order_line: + vendor_id = line.vendor_id.id + if vendor_id not in unique_partner_ids: + unique_partner_ids.add(vendor_id) + leadtime = line.vendor_id.leadtime + total_leadtime += leadtime + total_orders += 1 + + if total_orders > 0 and self.date_order and self.state not in ['cancel', 'draft']: + average_leadtime = total_leadtime / total_orders + rounded_average_leadtime = round(average_leadtime) + eta_date = self.date_order + timedelta(days=rounded_average_leadtime) + self.eta_date = eta_date + else: + self.eta_date = False def _prepare_invoice(self): """ diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index 58fff00a..da2dec99 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -23,6 +23,9 @@ + + + diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 18ae4c51..696cedc4 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -44,6 +44,9 @@ + + + -- cgit v1.2.3 From dfd4a1617d2c62b99d4bbcb6386b477874a33ebf Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 9 Jan 2024 15:03:15 +0700 Subject: multiple confirm purchase orders --- indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/purchase_order.py | 14 ++++++++++ .../models/purchase_order_multi_confirm.py | 22 +++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 3 ++- indoteknik_custom/views/purchase_order.xml | 9 +++++++ .../views/purchase_order_multi_confirm.xml | 31 ++++++++++++++++++++++ 7 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/purchase_order_multi_confirm.py create mode 100644 indoteknik_custom/views/purchase_order_multi_confirm.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index d6e69718..c7e65b37 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -105,6 +105,7 @@ 'views/customer_commision.xml', 'views/wati_history.xml', 'views/purchase_order_multi_update.xml', + 'views/purchase_order_multi_confirm.xml', 'views/invoice_reklas_penjualan.xml', 'report/report.xml', 'report/report_banner_banner.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 509fceef..e984d0dd 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -96,3 +96,4 @@ from . import commision from . import sale_advance_payment_inv from . import purchase_order_multi_update from . import invoice_reklas_penjualan +from . import purchase_order_multi_confirm diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index ba6b6c41..6a641aff 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -52,12 +52,26 @@ class PurchaseOrder(models.Model): responsible_ids = fields.Many2many('res.users', string='Responsibles', compute='_compute_responsibles') status_paid_cbd = fields.Boolean(string='Paid Status', tracking=3, help='Field ini diisi secara manual oleh Finance AP dan hanya untuk status PO CBD') + def open_form_multi_confirm_po(self): + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_purchase_order_multi_confirm') + action['context'] = { + 'order_ids': [x.id for x in self] + } + return action + def action_multi_update_paid_status(self): for purchase in self: purchase.update({ 'status_paid_cbd': True, }) + def action_multi_confirm_po(self): + for purchase in self: + if purchase.state != 'draft': + continue + + purchase.button_confirm() + def open_form_multi_update_paid_status(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_purchase_order_multi_update') action['context'] = { diff --git a/indoteknik_custom/models/purchase_order_multi_confirm.py b/indoteknik_custom/models/purchase_order_multi_confirm.py new file mode 100644 index 00000000..ac77ca54 --- /dev/null +++ b/indoteknik_custom/models/purchase_order_multi_confirm.py @@ -0,0 +1,22 @@ +from odoo import models, fields +import logging + +_logger = logging.getLogger(__name__) + + +class PurchaseOrderMultiUpdate(models.TransientModel): + _name = 'purchase.order.multi_confirm' + + def save_multi_confirm_po(self): + order_ids = self._context['order_ids'] + purchase = self.env['purchase.order'].browse(order_ids) + purchase.action_multi_confirm_po() + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Notification', + 'message': 'PO berhasil di Confirm', + 'next': {'type': 'ir.actions.act_window_close'}, + } + } \ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 8520961d..8d014b69 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -87,4 +87,5 @@ access_wati_history_line,access.wati.history.line,model_wati_history_line,,1,1,1 access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advance_payment_inv,,1,1,1,1 access_purchase_order_multi_update,access.purchase.order.multi_update,model_purchase_order_multi_update,,1,1,1,1 access_invoice_reklas_penjualan,access.invoice.reklas.penjualan,model_invoice_reklas_penjualan,,1,1,1,1 -access_invoice_reklas_penjualan_line,access.invoice.reklas.penjualan.line,model_invoice_reklas_penjualan_line,,1,1,1,1 \ No newline at end of file +access_invoice_reklas_penjualan_line,access.invoice.reklas.penjualan.line,model_invoice_reklas_penjualan_line,,1,1,1,1 +access_purchase_order_multi_confirm,access.purchase.order.multi_confirm,model_purchase_order_multi_confirm,,1,1,1,1 \ No newline at end of file diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 3a95393e..fff582b1 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -197,4 +197,13 @@ action = records.open_form_multi_update_paid_status() + + + Confirm PO + + + code + action = records.open_form_multi_confirm_po() + + \ No newline at end of file diff --git a/indoteknik_custom/views/purchase_order_multi_confirm.xml b/indoteknik_custom/views/purchase_order_multi_confirm.xml new file mode 100644 index 00000000..0d38be9e --- /dev/null +++ b/indoteknik_custom/views/purchase_order_multi_confirm.xml @@ -0,0 +1,31 @@ + + + + + Purchase Order Multi Confirm + purchase.order.multi_confirm + +
+ + + Apakah Anda Yakin Ingin Confirm PO Tersebut? + + +
+
+
+
+
+ + + Purchase Order Multi Confirm + purchase.order.multi_confirm + ir.actions.act_window + form + + new + +
+
\ No newline at end of file -- cgit v1.2.3 From e64e3a04ff6db3802779477398020738017b74b8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 10 Jan 2024 09:18:26 +0700 Subject: multiple delete on purchase order line --- indoteknik_custom/models/purchase_order.py | 4 ++++ indoteknik_custom/models/purchase_order_line.py | 1 + indoteknik_custom/views/purchase_order.xml | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 6a641aff..6d156cb6 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -52,6 +52,10 @@ class PurchaseOrder(models.Model): responsible_ids = fields.Many2many('res.users', string='Responsibles', compute='_compute_responsibles') status_paid_cbd = fields.Boolean(string='Paid Status', tracking=3, help='Field ini diisi secara manual oleh Finance AP dan hanya untuk status PO CBD') + def delete_line(self): + lines_to_delete = self.order_line.filtered(lambda line: line.delete) + lines_to_delete.unlink() + def open_form_multi_confirm_po(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_purchase_order_multi_confirm') action['context'] = { diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 9406f85f..9240c504 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -34,6 +34,7 @@ class PurchaseOrderLine(models.Model): is_ltc = fields.Boolean(string='Sudah di LTC', default=False, help='centang ini jika barang sudah di LTC') note = fields.Char(string='Note') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') + delete = fields.Boolean(string='Delete', default=False, help='centang ini jika anda ingin menghapus line ini') def _compute_qty_reserved(self): for line in self: diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index fff582b1..c7989eeb 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -23,6 +23,9 @@ + @@ -46,6 +49,7 @@ + {'no_create': True} -- cgit v1.2.3 From 893fbb7a4d1467686c4de435393f1162c4d04bd7 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 10 Jan 2024 09:23:41 +0700 Subject: fix error delete --- indoteknik_custom/models/purchase_order.py | 2 +- indoteknik_custom/models/purchase_order_line.py | 2 +- indoteknik_custom/views/purchase_order.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 6d156cb6..3c446fa7 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -53,7 +53,7 @@ class PurchaseOrder(models.Model): status_paid_cbd = fields.Boolean(string='Paid Status', tracking=3, help='Field ini diisi secara manual oleh Finance AP dan hanya untuk status PO CBD') def delete_line(self): - lines_to_delete = self.order_line.filtered(lambda line: line.delete) + lines_to_delete = self.order_line.filtered(lambda line: line.delete_line) lines_to_delete.unlink() def open_form_multi_confirm_po(self): diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 9240c504..807ee628 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -34,7 +34,7 @@ class PurchaseOrderLine(models.Model): is_ltc = fields.Boolean(string='Sudah di LTC', default=False, help='centang ini jika barang sudah di LTC') note = fields.Char(string='Note') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') - delete = fields.Boolean(string='Delete', default=False, help='centang ini jika anda ingin menghapus line ini') + delete_line = fields.Boolean(string='Delete', default=False, help='centang ini jika anda ingin menghapus line ini') def _compute_qty_reserved(self): for line in self: diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index c7989eeb..be01e980 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -49,7 +49,7 @@ - + {'no_create': True} -- cgit v1.2.3 From 25748d7a8d537ffe6a3e905f59f05a4d737499d9 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Wed, 10 Jan 2024 10:05:04 +0700 Subject: bug fix add tax in purchase pricelist if not have tax in purchase order --- indoteknik_custom/models/purchase_order.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 3c446fa7..44af8976 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -100,15 +100,19 @@ class PurchaseOrder(models.Model): for line in self.order_line: i += 1 current_time = datetime.utcnow() - print(i, len(self.order_line)) + # print(i, len(self.order_line)) price_unit = line.price_unit taxes = line.taxes_id for tax in taxes: tax_include = tax.price_include tax_amt = tax.amount if taxes: - if not tax_include: + if tax_include: price_unit = price_unit + (price_unit * tax_amt / 100) + else: + price_unit = price_unit + (price_unit * 11 / 100) + else: + price_unit = price_unit + (price_unit * 11 / 100) purchase_pricelist = self.env['purchase.pricelist'].search([ ('product_id', '=', line.product_id.id), -- cgit v1.2.3 From 5005eebb8fdd82db1e65a1d3de715d8bb5a63b32 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 10 Jan 2024 11:10:50 +0700 Subject: IU minus inventory validation --- indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/purchase_order.py | 2 ++ indoteknik_custom/models/stock_picking.py | 13 +++++++++++++ indoteknik_custom/models/stock_quant.py | 8 ++++++++ 4 files changed, 24 insertions(+) create mode 100644 indoteknik_custom/models/stock_quant.py diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index e984d0dd..76387ff8 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -97,3 +97,4 @@ from . import sale_advance_payment_inv from . import purchase_order_multi_update from . import invoice_reklas_penjualan from . import purchase_order_multi_confirm +from . import stock_quant diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 3c446fa7..b1dde1d5 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -54,6 +54,8 @@ class PurchaseOrder(models.Model): def delete_line(self): lines_to_delete = self.order_line.filtered(lambda line: line.delete_line) + if not lines_to_delete: + raise UserError('Tidak ada item yang dipilih') lines_to_delete.unlink() def open_form_multi_confirm_po(self): diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index a5e533b1..0c810ef7 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -281,6 +281,17 @@ class StockPicking(models.Model): self.is_internal_use = self.picking_type_id.is_internal_use return + def validation_minus_onhand_quantity(self): + bu_location_id = 57 + for line in self.move_line_ids_without_package: + quant = self.env['stock.quant'].search([ + ('product_id', '=', line.product_id.id), + ('location_id', '=', bu_location_id) + ]) + + if quant and quant.inventory_quantity < line.product_uom_qty: + raise UserError('Quantity reserved lebih besar dari quantity onhand di product') + def button_validate(self): if self._name != 'stock.picking': return super(StockPicking, self).button_validate() @@ -314,6 +325,8 @@ class StockPicking(models.Model): if not self.date_reserved: current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.date_reserved = current_time + + self.validation_minus_onhand_quantity() res = super(StockPicking, self).button_validate() self.calculate_line_no() diff --git a/indoteknik_custom/models/stock_quant.py b/indoteknik_custom/models/stock_quant.py new file mode 100644 index 00000000..9affcf4b --- /dev/null +++ b/indoteknik_custom/models/stock_quant.py @@ -0,0 +1,8 @@ +import logging + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +class StockQuant(models.Model): + _inherit = 'stock.quant' + + \ No newline at end of file -- cgit v1.2.3 From eedd71af67b880d7c07eb1137bf3c85a48881f48 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 12 Jan 2024 15:08:16 +0700 Subject: fix error looping on eta date so --- indoteknik_custom/models/sale_order.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 07fd60fc..ee7ed1fe 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -97,13 +97,14 @@ class SaleOrder(models.Model): total_leadtime += leadtime total_orders += 1 - if total_orders > 0 and self.date_order and self.state not in ['cancel', 'draft']: - average_leadtime = total_leadtime / total_orders - rounded_average_leadtime = round(average_leadtime) - eta_date = self.date_order + timedelta(days=rounded_average_leadtime) - self.eta_date = eta_date - else: - self.eta_date = False + for rec in self: + if total_orders > 0 and rec.date_order and rec.state not in ['cancel', 'draft']: + average_leadtime = total_leadtime / total_orders + rounded_average_leadtime = round(average_leadtime) + eta_date = rec.date_order + timedelta(days=rounded_average_leadtime) + rec.eta_date = eta_date + else: + rec.eta_date = False def _prepare_invoice(self): """ -- cgit v1.2.3 From 283baf2945adfbadaddd9fb0ca732df894189062 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 12 Jan 2024 15:42:16 +0700 Subject: fix validation iu minus on inventory --- indoteknik_custom/models/stock_picking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 0c810ef7..f6a21698 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -286,10 +286,10 @@ class StockPicking(models.Model): for line in self.move_line_ids_without_package: quant = self.env['stock.quant'].search([ ('product_id', '=', line.product_id.id), - ('location_id', '=', bu_location_id) + ('location_id', '=', bu_location_id), ]) - if quant and quant.inventory_quantity < line.product_uom_qty: + if self.sale_id and quant and quant.inventory_quantity < line.product_uom_qty: raise UserError('Quantity reserved lebih besar dari quantity onhand di product') def button_validate(self): -- cgit v1.2.3 From 7c348d0bd0f6e31c00351629f0c8cb6f36735f60 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 12 Jan 2024 16:34:34 +0700 Subject: nonaktif kode validation iu --- indoteknik_custom/models/stock_picking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index f6a21698..cebd5fc1 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -326,7 +326,7 @@ class StockPicking(models.Model): current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.date_reserved = current_time - self.validation_minus_onhand_quantity() + # self.validation_minus_onhand_quantity() res = super(StockPicking, self).button_validate() self.calculate_line_no() -- cgit v1.2.3 From a7a50ce0f4b80bf37c5abf8ba0f22ef1e2eeaf18 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 15 Jan 2024 13:25:50 +0700 Subject: fix iu minus inventory validation --- indoteknik_custom/models/stock_picking.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index cebd5fc1..c98b5f99 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -282,16 +282,22 @@ class StockPicking(models.Model): return def validation_minus_onhand_quantity(self): - bu_location_id = 57 + bu_location_id = 49 for line in self.move_line_ids_without_package: quant = self.env['stock.quant'].search([ ('product_id', '=', line.product_id.id), ('location_id', '=', bu_location_id), ]) - if self.sale_id and quant and quant.inventory_quantity < line.product_uom_qty: + if ( + self.picking_type_id.id == 29 + and quant + and line.location_id.id == bu_location_id + and quant.inventory_quantity < line.product_uom_qty + ): raise UserError('Quantity reserved lebih besar dari quantity onhand di product') + def button_validate(self): if self._name != 'stock.picking': return super(StockPicking, self).button_validate() -- cgit v1.2.3 From ba593bd2979efdad24ee025f32504b72002205d2 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 15 Jan 2024 15:39:28 +0700 Subject: PO revision without entering altama API --- indoteknik_custom/models/purchase_order.py | 8 +++++++- indoteknik_custom/views/purchase_order.xml | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 910b694d..92632ea3 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -51,6 +51,7 @@ class PurchaseOrder(models.Model): purchase_order_lines = fields.One2many('purchase.order.line', 'order_id', string='Indent', auto_join=True) responsible_ids = fields.Many2many('res.users', string='Responsibles', compute='_compute_responsibles') status_paid_cbd = fields.Boolean(string='Paid Status', tracking=3, help='Field ini diisi secara manual oleh Finance AP dan hanya untuk status PO CBD') + revisi_po = fields.Boolean(string='Revisi', tracking=3) def delete_line(self): lines_to_delete = self.order_line.filtered(lambda line: line.delete_line) @@ -293,6 +294,7 @@ class PurchaseOrder(models.Model): def button_confirm(self): res = super(PurchaseOrder, self).button_confirm() + current_time = datetime.now() if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: raise UserError("Beda Margin dengan Sales, harus approval Manager") @@ -310,6 +312,11 @@ class PurchaseOrder(models.Model): if send_email: self._send_mail() + + if self.revisi_po: + delta_time = current_time - timedelta(days=2) + delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') + self.date_approve = delta_time self.approval_status = 'approved' self.po_status = 'menunggu' @@ -318,7 +325,6 @@ class PurchaseOrder(models.Model): # override date planned added with two days leadtime = self.partner_id.leadtime - current_time = datetime.now() delta_time = current_time + timedelta(days=leadtime) delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') self.date_planned = delta_time diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index be01e980..48443057 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -31,6 +31,9 @@ + + + -- cgit v1.2.3 From 29597914fc972bb875ddd10977f2fa34f7a60a22 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 15 Jan 2024 17:06:22 +0700 Subject: activate function iu minus inventory validation --- indoteknik_custom/models/stock_picking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index c98b5f99..2819d6e7 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -332,7 +332,7 @@ class StockPicking(models.Model): current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.date_reserved = current_time - # self.validation_minus_onhand_quantity() + self.validation_minus_onhand_quantity() res = super(StockPicking, self).button_validate() self.calculate_line_no() -- cgit v1.2.3 From 3e268a5e9db10ad0b800cfe2f87801111eccd7a4 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 16 Jan 2024 10:05:19 +0700 Subject: Update api image with cache in controller --- indoteknik_api/controllers/controller.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 4d6716b2..85eda235 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -3,7 +3,7 @@ import datetime import base64 import json -from odoo import http +from odoo import http, tools from odoo.http import request from odoo.tools.config import config from pytz import timezone @@ -185,5 +185,12 @@ 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')]) + + response_headers = [('Content-Type', 'image/jpg'), ('Cache-Control', 'public, max-age=3600')] + + return request.make_response( + base64.b64decode(image), + response_headers + ) -- cgit v1.2.3 From da4ec7e5513cd9975a0b503857e49598a2dee158 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 16 Jan 2024 13:31:23 +0700 Subject: add link sale order to invoices when create invoices --- indoteknik_custom/models/sale_order.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ee7ed1fe..7af24be9 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -129,6 +129,7 @@ class SaleOrder(models.Model): 'medium_id': self.medium_id.id, 'source_id': self.source_id.id, 'user_id': self.user_id.id, + 'sale_id': self.id, 'invoice_user_id': self.user_id.id, 'team_id': self.team_id.id, 'partner_id': parent_id.id, -- cgit v1.2.3 From 37bb5cfca00b841f8204ebbc9dd5f88bbd6cc022 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 17 Jan 2024 17:01:20 +0700 Subject: fix function update_internal_reference --- indoteknik_custom/models/product_template.py | 50 ++++++++++++++++------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 34aff4fa..4beef751 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -74,7 +74,7 @@ class ProductTemplate(models.Model): @api.constrains('name', 'default_code') def _check_duplicate_product(self): for product in self: - if not self.env.user.is_purchasing_manager and not self.env.user.is_editor_product: + if not self.env.user.is_purchasing_manager and not self.env.user.is_editor_product and self.env.user.id not in [1, 25]: domain = [('default_code', '!=', False)] if product.product_variant_ids: @@ -157,28 +157,34 @@ class ProductTemplate(models.Model): _logger.info('Updated New Product %s' % product.name) def update_internal_reference(self, limit=100): - templates_without_variant = self.env['product.template'].search([ + templates = self.env['product.template'].search([ ('default_code', '=', False), + ('product_variant_ids.default_code', '=', False), ('type', '=', 'product'), - ('active', '=', True), - ('product_variant_ids', '=', False), - ], limit=limit) - for template_without_variant in templates_without_variant: - template_without_variant.default_code = 'IT.'+str(template_without_variant.id) - _logger.info('Updated Template %s' % template_without_variant.name) - - templates_with_variant = self.env['product.template'].search([ - ('default_code', '=', False), - ('type', '=', 'product'), - ('active', '=', True), - ('product_variant_ids', '!=', False), - ], limit=limit) - for template_with_variant in templates_with_variant: - for product in template_with_variant.product_variant_ids: - if product.default_code: - continue - product.default_code = 'ITV.'+str(product.id) - _logger.info('Updated Variant %s' % product.name) + ('active', '=', True) + ], limit=limit, order='write_date desc') + for template in templates: + if not template.default_code: + template.default_code = 'IT.'+str(template.id) + + for variant in template.product_variant_ids: + if not variant.default_code: + variant.default_code = 'ITV.%s' % str(variant.id) + + _logger.info('Updated Template %s' % template.name) + + # templates_with_variant = self.env['product.product'].search([ + # ('default_code', '=', False), + # ('type', '=', 'product'), + # ('active', '=', True), + # ('product_tmpl_id', '!=', False), + # ], limit=limit, order='write_date desc') + # for template_with_variant in templates_with_variant: + # for product in template_with_variant.product_variant_ids: + # if product.default_code: + # continue + # product.default_code = 'ITV.'+str(product.id) + # _logger.info('Updated Variant %s' % product.name) @api.onchange('name','default_code','x_manufacture','product_rating','website_description','image_1920','weight','public_categ_ids') def update_solr_flag(self): @@ -372,7 +378,7 @@ class ProductProduct(models.Model): @api.constrains('name','default_code') def _check_duplicate_product(self): for product in self: - if not self.env.user.is_purchasing_manager and not self.env.user.is_editor_product: + if not self.env.user.is_purchasing_manager and not self.env.user.is_editor_product and self.env.user.id not in [1, 25]: if product.write_date == product.create_date: domain = [ ('default_code', '!=', False), -- cgit v1.2.3 From fb62bc36bf74496ecc4759b01cf95fce5000c09c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 18 Jan 2024 11:34:54 +0700 Subject: command bug function --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 92632ea3..b44ce70a 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -301,7 +301,7 @@ class PurchaseOrder(models.Model): if not self.sale_order_id and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Manager") send_email = False - self.add_product_to_pricelist() + # self.add_product_to_pricelist() for line in self.order_line: if not line.product_id.purchase_ok: raise UserError("Terdapat barang yang tidak bisa diproses") -- cgit v1.2.3 From c6e75269c4d3f0471e14cdf5b03f6a94aaed12d0 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 22 Jan 2024 11:27:51 +0700 Subject: Update get valid purchase price in sale order line --- indoteknik_custom/models/sale_order_line.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 358cbfe2..ab20fb09 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -93,17 +93,16 @@ class SaleOrderLine(models.Model): self.purchase_tax_id = 22 def _get_valid_purchase_price(self, purchase_price): - p_price = 0 + price = purchase_price.system_price or purchase_price.product_price or 0 + if purchase_price.system_price > 0 and purchase_price.product_price > 0: - if purchase_price.human_last_update > purchase_price.system_last_update: - p_price = purchase_price.product_price - else: - p_price = purchase_price.system_price - elif purchase_price.system_price > 0 and purchase_price.product_price == 0: - p_price = purchase_price.system_price - elif purchase_price.system_price == 0 and purchase_price.product_price > 0: - p_price = purchase_price.product_price - return p_price + if purchase_price.human_last_update == False or purchase_price.system_last_update > purchase_price.human_last_update: + price = purchase_price.system_price + + if purchase_price.system_last_update == False or purchase_price.human_last_update > purchase_price.system_last_update: + price = purchase_price.product_price + + return price @api.onchange('product_id') def product_id_change(self): -- cgit v1.2.3 From b972e53c1a1b184123327b18ef89517e3c075ad6 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 22 Jan 2024 11:36:03 +0700 Subject: Fix _get_valid_purchase_price in sale order line --- indoteknik_custom/models/sale_order_line.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index ab20fb09..78944876 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -96,10 +96,12 @@ class SaleOrderLine(models.Model): price = purchase_price.system_price or purchase_price.product_price or 0 if purchase_price.system_price > 0 and purchase_price.product_price > 0: - if purchase_price.human_last_update == False or purchase_price.system_last_update > purchase_price.human_last_update: + if not purchase_price.human_last_update or not purchase_price.system_last_update: + return price + + if purchase_price.system_last_update > purchase_price.human_last_update: price = purchase_price.system_price - - if purchase_price.system_last_update == False or purchase_price.human_last_update > purchase_price.system_last_update: + else: price = purchase_price.product_price return price -- cgit v1.2.3 From 931955161ec87ef152f9c76bee9f6c0abd81a2b5 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 22 Jan 2024 13:22:10 +0700 Subject: Update get valid purchase price di sale order line --- indoteknik_custom/models/sale_order_line.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 78944876..62f4a6b4 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -1,5 +1,6 @@ from odoo import fields, models, api, _ from odoo.exceptions import UserError +from datetime import datetime class SaleOrderLine(models.Model): @@ -93,18 +94,16 @@ class SaleOrderLine(models.Model): self.purchase_tax_id = 22 def _get_valid_purchase_price(self, purchase_price): - price = purchase_price.system_price or purchase_price.product_price or 0 - - if purchase_price.system_price > 0 and purchase_price.product_price > 0: - if not purchase_price.human_last_update or not purchase_price.system_last_update: - return price - - if purchase_price.system_last_update > purchase_price.human_last_update: - price = purchase_price.system_price - else: - price = purchase_price.product_price + price = 0 + human_last_update = purchase_price.human_last_update or datetime.min + system_last_update = purchase_price.system_last_update or datetime.min + + if system_last_update > human_last_update: + price = purchase_price.system_price + else: + price = purchase_price.product_price - return price + return price or 0 @api.onchange('product_id') def product_id_change(self): -- cgit v1.2.3 From 24b383b580ae039d66e06a9b20b000b19f833033 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 22 Jan 2024 14:46:13 +0700 Subject: Add watermark in api get image --- indoteknik_api/controllers/controller.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 85eda235..7278ec23 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -7,8 +7,10 @@ from odoo import http, tools from odoo.http import request from odoo.tools.config import config from pytz import timezone +from PIL import Image, ImageDraw, ImageFont import jwt import functools +import io class Controller(http.Controller): @@ -182,11 +184,26 @@ class Controller(http.Controller): return self.response(address) @http.route('/api/image///', auth='public', methods=['GET']) - def get_image(self, model, field, id): + def get_image(self, model, field, id, **kw): + watermark = kw.get('watermark', '') model = request.env[model].sudo().search([('id', '=', id)], limit=1) image = model[field] if model[field] else '' - request.env['user.activity.log'].record_activity() + if watermark.lower() == 'true': + img_data = io.BytesIO(base64.b64decode(image)) + img = Image.open(img_data) + + img_width, img_height = img.size + font_size = int(min(img_width, img_height) * 0.04) + font = ImageFont.truetype("arial.ttf", font_size) + + img = img.convert('RGBA') + draw = ImageDraw.Draw(img) + draw.text((10, 10), 'Indoteknik.com', fill=(0, 0, 0, 100), font=font) + + buffered = io.BytesIO() + img.save(buffered, format="PNG") + image = base64.b64encode(buffered.getvalue()).decode('utf-8') response_headers = [('Content-Type', 'image/jpg'), ('Cache-Control', 'public, max-age=3600')] -- cgit v1.2.3 From 5ed6910d689197416d0c87d269dd8362c079b831 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 22 Jan 2024 15:04:05 +0700 Subject: Add font in indoteknik_api --- indoteknik_api/controllers/controller.py | 4 +++- indoteknik_api/static/src/fonts/Inter.ttf | Bin 0 -> 805360 bytes 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 indoteknik_api/static/src/fonts/Inter.ttf diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 7278ec23..95b7d838 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -6,6 +6,7 @@ import json from odoo import http, tools from odoo.http import request from odoo.tools.config import config +from odoo.modules import get_module_resource from pytz import timezone from PIL import Image, ImageDraw, ImageFont import jwt @@ -195,7 +196,8 @@ class Controller(http.Controller): img_width, img_height = img.size font_size = int(min(img_width, img_height) * 0.04) - font = ImageFont.truetype("arial.ttf", font_size) + font_path = get_module_resource('indoteknik_api', 'static', 'src', 'fonts', 'Inter.ttf') + font = ImageFont.truetype(font_path, font_size) img = img.convert('RGBA') draw = ImageDraw.Draw(img) diff --git a/indoteknik_api/static/src/fonts/Inter.ttf b/indoteknik_api/static/src/fonts/Inter.ttf new file mode 100644 index 00000000..1cb674b7 Binary files /dev/null and b/indoteknik_api/static/src/fonts/Inter.ttf differ -- cgit v1.2.3 From 3939395d033d8d10f279bc7dd501bc7fbf1a035e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 22 Jan 2024 15:06:14 +0700 Subject: add column to purchase pricelist --- indoteknik_custom/models/purchase_pricelist.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 86bb2f54..b85df109 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -11,12 +11,14 @@ class PurchasePricelist(models.Model): product_id = fields.Many2one('product.product', string="Product", required=True) vendor_id = fields.Many2one('res.partner', string="Vendor", required=True) product_price = fields.Float(string='Human Price', required=True) - system_price = fields.Float(string='System Price', required=True) + system_price = fields.Float(string='System Price', readonly=True) human_last_update = fields.Datetime(string='Human Update') system_last_update = fields.Datetime(string='System Update') count_trx_po = fields.Integer(string='Count Trx Product') count_trx_po_vendor = fields.Integer(string='Count Trx Vendor') - + taxes_product_id = fields.Many2one('account.tax', string='Taxes Human') + taxes_system_id = fields.Many2one('account.tax', string='Taxes System', readonly=True) + include_price = fields.Float(string='Include Price', readonly=True) @api.depends('product_id', 'vendor_id') def _compute_name(self): self.name = self.vendor_id.name + ', ' + self.product_id.name @@ -30,6 +32,21 @@ class PurchasePricelist(models.Model): else: self.human_last_update = current_time + # @api.constrains('system_last_update','system_price') + # def _contrains_include_price(self): + # taxes = self.taxes_system_id or self.taxes_product_id + # tax_include = taxes.price_include + # price_unit = self.system_price or self.product_price + # if taxes: + # if tax_include: + # price_unit = price_unit + # else: + # price_unit = price_unit + (price_unit * 11 / 100) + # else: + # price_unit = price_unit + (price_unit * 11 / 100) + + # self.include_price = price_unit + @api.constrains('vendor_id', 'product_id') def _check_duplicate_purchase_pricelist(self): for price in self: -- cgit v1.2.3 From 14545d90b2c35a61c1a269c48b480dc82a099510 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 22 Jan 2024 15:13:43 +0700 Subject: add column to purchase pricelist --- indoteknik_custom/views/purchase_pricelist.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indoteknik_custom/views/purchase_pricelist.xml b/indoteknik_custom/views/purchase_pricelist.xml index f4cd4e78..df379804 100755 --- a/indoteknik_custom/views/purchase_pricelist.xml +++ b/indoteknik_custom/views/purchase_pricelist.xml @@ -8,7 +8,10 @@ + + + @@ -28,7 +31,10 @@ + + + -- cgit v1.2.3 From 10c3e0308d8c71654e451b2f3b06083b7b1b7791 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 22 Jan 2024 15:23:39 +0700 Subject: Fix bug schedule date plan --- indoteknik_custom/models/purchase_order.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index b44ce70a..7a575748 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -289,6 +289,8 @@ class PurchaseOrder(models.Model): def date_deadline_ref_date_planned(self): for picking in self.picking_ids: + if picking.state in ['done', 'cancel']: + continue picking.scheduled_date = self.date_planned picking.date_deadline = self.date_planned -- cgit v1.2.3 From 53d5d5869f62d73be785400c050b389efb10b511 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 22 Jan 2024 15:32:43 +0700 Subject: change request on eta_date --- indoteknik_custom/models/sale_order.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 7af24be9..44790480 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -85,23 +85,15 @@ class SaleOrder(models.Model): eta_date = fields.Datetime(string='ETA Date', tracking=3, copy=False, compute='_compute_eta_date') def _compute_eta_date(self): - unique_partner_ids = set() - total_leadtime = 0 - total_orders = 0 + max_leadtime = 0 for line in self.order_line: - vendor_id = line.vendor_id.id - if vendor_id not in unique_partner_ids: - unique_partner_ids.add(vendor_id) - leadtime = line.vendor_id.leadtime - total_leadtime += leadtime - total_orders += 1 + leadtime = line.vendor_id.leadtime + max_leadtime = max(max_leadtime, leadtime) for rec in self: - if total_orders > 0 and rec.date_order and rec.state not in ['cancel', 'draft']: - average_leadtime = total_leadtime / total_orders - rounded_average_leadtime = round(average_leadtime) - eta_date = rec.date_order + timedelta(days=rounded_average_leadtime) + if rec.date_order and rec.state not in ['cancel', 'draft']: + eta_date = datetime.now() + timedelta(days=max_leadtime) rec.eta_date = eta_date else: rec.eta_date = False -- cgit v1.2.3 From e5dbcd62560f4083d413d474b123ed971926a2a0 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 22 Jan 2024 16:58:11 +0700 Subject: final fix bug purchase pricelist --- indoteknik_custom/models/automatic_purchase.py | 17 ++++++++++---- indoteknik_custom/models/purchase_order.py | 28 +++++++++++----------- indoteknik_custom/models/purchase_order_line.py | 31 +++++++++++++++++++++---- indoteknik_custom/models/purchase_pricelist.py | 26 ++++++++++----------- 4 files changed, 67 insertions(+), 35 deletions(-) diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 502761e0..7b02a13e 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -89,9 +89,9 @@ class AutomaticPurchase(models.Model): query = [ ('product_min_qty', '>', 0), - ('product_id.x_manufacture.user_id.id', '=', self.responsible_id.id) + # ('product_id.x_manufacture.user_id.id', '=', self.responsible_id.id) ] - orderpoints = self.env['stock.warehouse.orderpoint'].search(query) + orderpoints = self.env['stock.warehouse.orderpoint'].search(query, limit=100) count = 0 for point in orderpoints: # _logger.info('test %s' % point.product_id.name) @@ -113,7 +113,7 @@ class AutomaticPurchase(models.Model): ], order='count_trx_po desc, count_trx_po_vendor desc', limit=1) vendor_id = purchase_price.vendor_id.id - price = self._get_valid_purchase_price(purchase_price) + price, taxes = self._get_valid_purchase_price(purchase_price) if self.vendor_id and self.vendor_id.id != vendor_id: continue @@ -129,6 +129,7 @@ class AutomaticPurchase(models.Model): # 'last_price': po_line.price_unit, 'partner_id': vendor_id, 'last_price': price, + 'taxes_id': taxes, 'subtotal': qty_purchase * price, 'last_order_id': po_line.order_id.id, 'last_orderline_id': po_line.id, @@ -142,14 +143,19 @@ class AutomaticPurchase(models.Model): p_price = 0 if purchase_price.system_price > 0 and purchase_price.product_price > 0: if purchase_price.human_last_update > purchase_price.system_last_update: - p_price = purchase_price.product_price + p_price = purchase_price.product_price + taxes = purchase_price.taxes_product_id else: p_price = purchase_price.system_price + taxes = purchase_price.taxes_system_id elif purchase_price.system_price > 0 and purchase_price.product_price == 0: p_price = purchase_price.system_price + taxes = purchase_price.taxes_system_id elif purchase_price.system_price == 0 and purchase_price.product_price > 0: p_price = purchase_price.product_price - return p_price + taxes = purchase_price.taxes_product_id + + return p_price, taxes class AutomaticPurchaseLine(models.Model): @@ -172,6 +178,7 @@ class AutomaticPurchaseLine(models.Model): current_po_id = fields.Many2one('purchase.order', string='Current') current_po_line_id = fields.Many2one('purchase.order.line', string='Current Line') brand_id = fields.Many2one('x_manufactures', string='Brand') + taxes_id = fields.Many2one('x_manufactures', string='Brand') class AutomaticPurchaseMatch(models.Model): diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 7a575748..5303f2c3 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -104,18 +104,18 @@ class PurchaseOrder(models.Model): i += 1 current_time = datetime.utcnow() # print(i, len(self.order_line)) + price_unit = line.price_unit taxes = line.taxes_id - for tax in taxes: - tax_include = tax.price_include - tax_amt = tax.amount - if taxes: - if tax_include: - price_unit = price_unit + (price_unit * tax_amt / 100) - else: - price_unit = price_unit + (price_unit * 11 / 100) - else: - price_unit = price_unit + (price_unit * 11 / 100) + # for tax in taxes: + # tax_include = tax.price_include + # if taxes: + # if tax_include: + # price_unit = price_unit + # else: + # price_unit = price_unit + (price_unit * 11 / 100) + # else: + # price_unit = price_unit + (price_unit * 11 / 100) purchase_pricelist = self.env['purchase.pricelist'].search([ ('product_id', '=', line.product_id.id), @@ -126,13 +126,15 @@ class PurchaseOrder(models.Model): purchase_pricelist.create([{ 'vendor_id': line.order_id.partner_id.id, 'product_id': line.product_id.id, - 'product_price': 0.00, + 'product_price': 0, + 'taxes_system_id': taxes.id, 'system_price': price_unit, - 'system_last_update': current_time, + 'system_last_update': current_time }]) else: purchase_pricelist.write({ 'system_last_update': current_time, + 'taxes_system_id': taxes.id, 'system_price': price_unit }) @@ -303,7 +305,7 @@ class PurchaseOrder(models.Model): if not self.sale_order_id and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Manager") send_email = False - # self.add_product_to_pricelist() + self.add_product_to_pricelist() for line in self.order_line: if not line.product_id.purchase_ok: raise UserError("Terdapat barang yang tidak bisa diproses") diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 807ee628..c7da0e24 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -78,14 +78,12 @@ class PurchaseOrderLine(models.Model): def _onchange_product_custom(self): self._compute_qty_stock() - # Override method from addons/purchase/models/purchase.py - @api.onchange('product_qty', 'product_uom') + @api.onchange('product_id','product_qty', 'product_uom') def _onchange_quantity(self): res = super(PurchaseOrderLine, self)._onchange_quantity() - # Custom script purchase_pricelist = self.env['purchase.pricelist'].search([ ('product_id', '=', self.product_id.id), - ('vendor_id', '=', self.partner_id.id) + ('vendor_id', '=', self.partner_id.id), ], limit=1) price_unit = purchase_pricelist.product_price @@ -96,8 +94,33 @@ class PurchaseOrderLine(models.Model): ], limit=1) price_unit = product_supplierinfo.price + price_unit, taxes = self._get_valid_purchase_price(purchase_pricelist) + self.price_unit = price_unit + if purchase_pricelist.taxes_product_id or purchase_pricelist.taxes_system_id: + self.taxes_id = taxes + return res + + def _get_valid_purchase_price(self, purchase_price): + p_price = 0 + taxes = False + + if purchase_price.system_price > 0 and purchase_price.product_price > 0: + if purchase_price.human_last_update > purchase_price.system_last_update: + p_price = purchase_price.product_price + taxes = purchase_price.taxes_product_id + else: + p_price = purchase_price.system_price + taxes = purchase_price.taxes_system_id + elif purchase_price.system_price > 0 and purchase_price.product_price == 0: + p_price = purchase_price.system_price + taxes = purchase_price.taxes_system_id + elif purchase_price.system_price == 0 and purchase_price.product_price > 0: + p_price = purchase_price.product_price + taxes = purchase_price.taxes_product_id + + return p_price, taxes def compute_item_margin(self): sum_so_margin = sum_sales_price = sum_margin = 0 diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index b85df109..9c149ea9 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -32,20 +32,20 @@ class PurchasePricelist(models.Model): else: self.human_last_update = current_time - # @api.constrains('system_last_update','system_price') - # def _contrains_include_price(self): - # taxes = self.taxes_system_id or self.taxes_product_id - # tax_include = taxes.price_include - # price_unit = self.system_price or self.product_price - # if taxes: - # if tax_include: - # price_unit = price_unit - # else: - # price_unit = price_unit + (price_unit * 11 / 100) - # else: - # price_unit = price_unit + (price_unit * 11 / 100) + @api.constrains('system_last_update','system_price') + def _contrains_include_price(self): + taxes = self.taxes_system_id or self.taxes_product_id + tax_include = taxes.price_include + price_unit = self.system_price or self.product_price + if taxes: + if tax_include: + price_unit = price_unit + else: + price_unit = price_unit + (price_unit * 11 / 100) + else: + price_unit = price_unit + (price_unit * 11 / 100) - # self.include_price = price_unit + self.include_price = price_unit @api.constrains('vendor_id', 'product_id') def _check_duplicate_purchase_pricelist(self): -- cgit v1.2.3 From f7fe2253a8c79ff5172cf74c1f1aa341c9bf4f07 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 23 Jan 2024 10:03:42 +0700 Subject: fix bug purchase pricelist, bug automatic purchase, bug log saleorder eta date --- indoteknik_custom/models/automatic_purchase.py | 4 ++-- indoteknik_custom/models/purchase_pricelist.py | 21 ++++++++++++++++++--- indoteknik_custom/models/sale_order.py | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 7b02a13e..3ab56e50 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -89,9 +89,9 @@ class AutomaticPurchase(models.Model): query = [ ('product_min_qty', '>', 0), - # ('product_id.x_manufacture.user_id.id', '=', self.responsible_id.id) + ('product_id.x_manufacture.user_id.id', '=', self.responsible_id.id) ] - orderpoints = self.env['stock.warehouse.orderpoint'].search(query, limit=100) + orderpoints = self.env['stock.warehouse.orderpoint'].search(query) count = 0 for point in orderpoints: # _logger.info('test %s' % point.product_id.name) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 9c149ea9..af33abbf 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -32,11 +32,12 @@ class PurchasePricelist(models.Model): else: self.human_last_update = current_time - @api.constrains('system_last_update','system_price') + @api.constrains('system_last_update','system_price','product_price','human_last_update') def _contrains_include_price(self): - taxes = self.taxes_system_id or self.taxes_product_id + price_unit, taxes = self._get_valid_price() + # taxes = self.taxes_system_id or self.taxes_product_id + # price_unit = self.system_price or self.product_price tax_include = taxes.price_include - price_unit = self.system_price or self.product_price if taxes: if tax_include: price_unit = price_unit @@ -47,6 +48,20 @@ class PurchasePricelist(models.Model): self.include_price = price_unit + def _get_valid_price(self): + p_price = 0 + taxes = False + + if self.system_price > 0: + if self.product_price > 0 and self.human_last_update > self.system_last_update: + p_price, taxes = self.product_price, self.taxes_product_id + else: + p_price, taxes = self.system_price, self.taxes_system_id + elif self.product_price > 0: + p_price, taxes = self.product_price, self.taxes_product_id + + return p_price, taxes + @api.constrains('vendor_id', 'product_id') def _check_duplicate_purchase_pricelist(self): for price in self: diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 44790480..f00f5b1d 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -82,7 +82,7 @@ class SaleOrder(models.Model): email = fields.Char(string='Email') picking_iu_id = fields.Many2one('stock.picking', 'Picking IU') helper_by_id = fields.Many2one('res.users', 'Helper By') - eta_date = fields.Datetime(string='ETA Date', tracking=3, copy=False, compute='_compute_eta_date') + eta_date = fields.Datetime(string='ETA Date', copy=False, compute='_compute_eta_date') def _compute_eta_date(self): max_leadtime = 0 -- cgit v1.2.3 From 50dfe6d8fa94b784c9cf62fcc6611131170c17e2 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 23 Jan 2024 10:08:26 +0700 Subject: Add watermark on image api --- indoteknik_api/controllers/controller.py | 42 ++++++++++++--------- .../static/src/images/logo-indoteknik.png | Bin 0 -> 29443 bytes 2 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 indoteknik_api/static/src/images/logo-indoteknik.png diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 95b7d838..36f5aa9b 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -186,30 +186,38 @@ class Controller(http.Controller): @http.route('/api/image///', auth='public', methods=['GET']) def get_image(self, model, field, id, **kw): - watermark = kw.get('watermark', '') model = request.env[model].sudo().search([('id', '=', id)], limit=1) image = model[field] if model[field] else '' + watermark = kw.get('watermark', '') if watermark.lower() == 'true': - img_data = io.BytesIO(base64.b64decode(image)) - img = Image.open(img_data) - - img_width, img_height = img.size - font_size = int(min(img_width, img_height) * 0.04) - font_path = get_module_resource('indoteknik_api', 'static', 'src', 'fonts', 'Inter.ttf') - font = ImageFont.truetype(font_path, font_size) - - img = img.convert('RGBA') - draw = ImageDraw.Draw(img) - draw.text((10, 10), 'Indoteknik.com', fill=(0, 0, 0, 100), font=font) - - buffered = io.BytesIO() - img.save(buffered, format="PNG") - image = base64.b64encode(buffered.getvalue()).decode('utf-8') + image = self.add_watermark_to_image(image) - response_headers = [('Content-Type', 'image/jpg'), ('Cache-Control', 'public, max-age=3600')] + response_headers = [ + ('Content-Type', 'image/jpg'), + ('Cache-Control', 'public, max-age=3600') + ] return request.make_response( base64.b64decode(image), response_headers ) + + def add_watermark_to_image(self, image): + logo_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', 'logo-indoteknik.png') + logo_img = Image.open(logo_path) + logo_img = logo_img.convert('RGBA') + + img_data = io.BytesIO(base64.b64decode(image)) + img = Image.open(img_data) + img = img.convert('RGBA') + + img_width, img_height = img.size + logo_img.thumbnail((img_width // 3, img_height // 3)) + + img.paste(logo_img, (20, 15), logo_img) + + buffered = io.BytesIO() + img.save(buffered, format="PNG") + return base64.b64encode(buffered.getvalue()).decode('utf-8') + diff --git a/indoteknik_api/static/src/images/logo-indoteknik.png b/indoteknik_api/static/src/images/logo-indoteknik.png new file mode 100644 index 00000000..0770c265 Binary files /dev/null and b/indoteknik_api/static/src/images/logo-indoteknik.png differ -- cgit v1.2.3 From 266f1cee69959dc47dc3e66e0448a7c5c09f9e1a Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 23 Jan 2024 10:14:55 +0700 Subject: add vendor to sale monitoring detail --- indoteknik_custom/models/sale_monitoring_detail.py | 1 + indoteknik_custom/views/sale_monitoring_detail.xml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py index 43b0b063..196a09cd 100755 --- a/indoteknik_custom/models/sale_monitoring_detail.py +++ b/indoteknik_custom/models/sale_monitoring_detail.py @@ -23,6 +23,7 @@ class SaleMonitoringDetail(models.Model): status = fields.Char(string="Status") qty_reserved = fields.Integer(string="Qty Reserved") note = fields.Char(string="Note") + vendor_id = fields.Many2one('res.partner', string='Vendor', related='sale_order_id.order_line.vendor_id') def init(self): tools.drop_view_if_exists(self.env.cr, self._table) diff --git a/indoteknik_custom/views/sale_monitoring_detail.xml b/indoteknik_custom/views/sale_monitoring_detail.xml index ce5b8e9b..e1363894 100755 --- a/indoteknik_custom/views/sale_monitoring_detail.xml +++ b/indoteknik_custom/views/sale_monitoring_detail.xml @@ -10,6 +10,7 @@ + @@ -40,6 +41,7 @@ + Date: Tue, 23 Jan 2024 10:53:29 +0700 Subject: fix constrains purchase price list --- indoteknik_custom/models/purchase_pricelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index af33abbf..10326c83 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -32,7 +32,7 @@ class PurchasePricelist(models.Model): else: self.human_last_update = current_time - @api.constrains('system_last_update','system_price','product_price','human_last_update') + @api.constrains('system_last_update','system_price','product_price','human_last_update','taxes_system_id','taxes_product_id') def _contrains_include_price(self): price_unit, taxes = self._get_valid_price() # taxes = self.taxes_system_id or self.taxes_product_id -- cgit v1.2.3 From cd915ccc6ade5eb6c837597ae5a18298a6902aaf Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 23 Jan 2024 10:54:24 +0700 Subject: change name field --- indoteknik_custom/models/purchase_pricelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 10326c83..98f51d03 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -18,7 +18,7 @@ class PurchasePricelist(models.Model): count_trx_po_vendor = fields.Integer(string='Count Trx Vendor') taxes_product_id = fields.Many2one('account.tax', string='Taxes Human') taxes_system_id = fields.Many2one('account.tax', string='Taxes System', readonly=True) - include_price = fields.Float(string='Include Price', readonly=True) + include_price = fields.Float(string='Final Price', readonly=True) @api.depends('product_id', 'vendor_id') def _compute_name(self): self.name = self.vendor_id.name + ', ' + self.product_id.name -- cgit v1.2.3 From 5c07394e695ee3e92d7dfa55f46bf566afb90a7c Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 23 Jan 2024 11:05:12 +0700 Subject: filter domain taxes human --- indoteknik_custom/models/purchase_pricelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 98f51d03..43efb7b5 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -16,7 +16,7 @@ class PurchasePricelist(models.Model): system_last_update = fields.Datetime(string='System Update') count_trx_po = fields.Integer(string='Count Trx Product') count_trx_po_vendor = fields.Integer(string='Count Trx Vendor') - taxes_product_id = fields.Many2one('account.tax', string='Taxes Human') + taxes_product_id = fields.Many2one('account.tax', string='Taxes Human', domain=[('type_tax_use', '=', 'purchase')]) taxes_system_id = fields.Many2one('account.tax', string='Taxes System', readonly=True) include_price = fields.Float(string='Final Price', readonly=True) @api.depends('product_id', 'vendor_id') -- cgit v1.2.3 From f7e412da7e3d2a106dee5a02e41101237213af2d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 23 Jan 2024 13:02:48 +0700 Subject: add vendor to sale detail --- indoteknik_custom/models/sale_monitoring_detail.py | 3 ++- indoteknik_custom/views/sale_monitoring_detail.xml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py index 196a09cd..ef2c832f 100755 --- a/indoteknik_custom/models/sale_monitoring_detail.py +++ b/indoteknik_custom/models/sale_monitoring_detail.py @@ -23,7 +23,7 @@ class SaleMonitoringDetail(models.Model): status = fields.Char(string="Status") qty_reserved = fields.Integer(string="Qty Reserved") note = fields.Char(string="Note") - vendor_id = fields.Many2one('res.partner', string='Vendor', related='sale_order_id.order_line.vendor_id') + vendor_id = fields.Many2one('res.partner', string='Vendor') def init(self): tools.drop_view_if_exists(self.env.cr, self._table) @@ -55,6 +55,7 @@ class SaleMonitoringDetail(models.Model): get_qty_po(so.id, sol.product_id) AS qty_po, get_qty_received(so.id, sol.product_id) AS qty_po_received, get_qty_reserved(so.id, sol.product_id) as qty_reserved, + get_vendor_id(so.id, sol.product_id) as vendor_id, sol.note_procurement as note FROM sale_order so JOIN sale_order_line sol ON sol.order_id = so.id diff --git a/indoteknik_custom/views/sale_monitoring_detail.xml b/indoteknik_custom/views/sale_monitoring_detail.xml index e1363894..5091fb83 100755 --- a/indoteknik_custom/views/sale_monitoring_detail.xml +++ b/indoteknik_custom/views/sale_monitoring_detail.xml @@ -76,6 +76,7 @@ + -- cgit v1.2.3 From 1bb1627bbf9b0224d6f6dafa586b4fe9c7aa9c19 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 23 Jan 2024 13:08:23 +0700 Subject: Add display on homepage column on promotion program line --- indoteknik_custom/models/promotion/promotion_program_line.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/promotion/promotion_program_line.py b/indoteknik_custom/models/promotion/promotion_program_line.py index d77123ce..18a7e184 100644 --- a/indoteknik_custom/models/promotion/promotion_program_line.py +++ b/indoteknik_custom/models/promotion/promotion_program_line.py @@ -20,6 +20,7 @@ class PromotionProgramLine(models.Model): product_ids = fields.One2many('promotion.product', 'program_line_id', 'Product') free_product_ids = fields.One2many('promotion.free_product', 'program_line_id', 'Free Product') + display_on_homepage = fields.Boolean('Display on Homepage') price = fields.Float('Price') discount_type = fields.Selection([ -- cgit v1.2.3 From d87bcdfe5e6e49e31dce5c423bcdaa4dfba9623e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 23 Jan 2024 14:00:37 +0700 Subject: change request sale_order_sync --- indoteknik_custom/models/purchase_order.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 5303f2c3..ebadff06 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -249,6 +249,8 @@ class PurchaseOrder(models.Model): self.order_line.unlink() for order_line in self.sale_order_id.order_line: + if order_line.vendor_id != self.partner_id: + continue if order_line.product_id.id and order_line.product_id.id not in products_exception: qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty -- cgit v1.2.3 From fcc5103a5cc1816fade1a59ae8852e387a744553 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 23 Jan 2024 14:18:44 +0700 Subject: add qty bandengan in product variant menu inventory --- indoteknik_custom/models/product_template.py | 14 ++++++++++---- indoteknik_custom/views/product_product.xml | 5 +++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 4beef751..bdbc391d 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -345,10 +345,11 @@ class ProductProduct(models.Model): usage = fields.Char(string='Usage') specification = fields.Char(string='Specification') material = fields.Char(string='Material') - qty_onhand_bandengan = fields.Float(string='Qty Onhand Bandengan', compute='_get_qty_onhand_bandengan') - qty_incoming_bandengan = fields.Float(string='Qty Incoming Bandengan', compute='_get_qty_incoming_bandengan') - qty_outgoing_bandengan = fields.Float(string='Qty Outgoing Bandengan', compute='_get_qty_outgoing_bandengan') - qty_available_bandengan = fields.Float(string='Qty Available Bandengan', compute='_get_qty_available_bandengan') + qty_onhand_bandengan = fields.Float(string='Onhand BU', compute='_get_qty_onhand_bandengan') + qty_incoming_bandengan = fields.Float(string='Incoming BU', compute='_get_qty_incoming_bandengan') + qty_outgoing_bandengan = fields.Float(string='Outgoing BU', compute='_get_qty_outgoing_bandengan') + qty_available_bandengan = fields.Float(string='Available BU', compute='_get_qty_available_bandengan') + qty_free_bandengan = fields.Float(string='Free BU', compute='_get_qty_free_bandengan') qty_upcoming = fields.Float(string='Qty Upcoming', compute='_get_qty_upcoming') sla_version = fields.Integer(string="SLA Version", default=0) is_edited = fields.Boolean(string='Is Edited') @@ -440,6 +441,11 @@ class ProductProduct(models.Model): for product in self: qty_available = product.qty_incoming_bandengan + product.qty_onhand_bandengan - product.qty_outgoing_bandengan product.qty_available_bandengan = qty_available + + def _get_qty_free_bandengan(self): + for product in self: + qty_free = product.qty_onhand_bandengan - product.qty_outgoing_bandengan + product.qty_free_bandengan = qty_free # def write(self, vals): # if 'solr_flag' not in vals: diff --git a/indoteknik_custom/views/product_product.xml b/indoteknik_custom/views/product_product.xml index 8194f92c..52043025 100644 --- a/indoteknik_custom/views/product_product.xml +++ b/indoteknik_custom/views/product_product.xml @@ -9,6 +9,11 @@ + + + + + -- cgit v1.2.3 From ac648884d21560f5cc32ad432121b05e6758d708 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 23 Jan 2024 14:42:30 +0700 Subject: change column sequence in product variant --- indoteknik_custom/views/product_product.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indoteknik_custom/views/product_product.xml b/indoteknik_custom/views/product_product.xml index 52043025..c06cc5f1 100644 --- a/indoteknik_custom/views/product_product.xml +++ b/indoteknik_custom/views/product_product.xml @@ -9,6 +9,8 @@ + + -- cgit v1.2.3 From 331671549aacb0d8f6b4448a4e788fd530f78654 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 23 Jan 2024 15:32:58 +0700 Subject: fix automatic purchase --- indoteknik_custom/models/automatic_purchase.py | 31 ++++++++++++-------------- indoteknik_custom/models/purchase_pricelist.py | 2 +- indoteknik_custom/views/automatic_purchase.xml | 1 + 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index 3ab56e50..bf6901d3 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -140,22 +140,19 @@ class AutomaticPurchase(models.Model): self.notification = "Automatic PO Created %s Lines" % count def _get_valid_purchase_price(self, purchase_price): - p_price = 0 - if purchase_price.system_price > 0 and purchase_price.product_price > 0: - if purchase_price.human_last_update > purchase_price.system_last_update: - p_price = purchase_price.product_price - taxes = purchase_price.taxes_product_id - else: - p_price = purchase_price.system_price - taxes = purchase_price.taxes_system_id - elif purchase_price.system_price > 0 and purchase_price.product_price == 0: - p_price = purchase_price.system_price - taxes = purchase_price.taxes_system_id - elif purchase_price.system_price == 0 and purchase_price.product_price > 0: - p_price = purchase_price.product_price - taxes = purchase_price.taxes_product_id - - return p_price, taxes + price = 0 + taxes = None + human_last_update = purchase_price.human_last_update or datetime.min + system_last_update = purchase_price.system_last_update or datetime.min + + if system_last_update > human_last_update: + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id + else: + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id + + return price, taxes class AutomaticPurchaseLine(models.Model): @@ -178,7 +175,7 @@ class AutomaticPurchaseLine(models.Model): current_po_id = fields.Many2one('purchase.order', string='Current') current_po_line_id = fields.Many2one('purchase.order.line', string='Current Line') brand_id = fields.Many2one('x_manufactures', string='Brand') - taxes_id = fields.Many2one('x_manufactures', string='Brand') + taxes_id = fields.Many2one('account.tax', string='Taxes') class AutomaticPurchaseMatch(models.Model): diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 43efb7b5..c756c301 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -23,7 +23,7 @@ class PurchasePricelist(models.Model): def _compute_name(self): self.name = self.vendor_id.name + ', ' + self.product_id.name - @api.constrains('product_price','system_price','vendor_id','product_id') + @api.constrains('product_price','system_price','vendor_id','product_id','taxes_system_id','taxes_product_id') def _contrains_product_price(self): current_time = fields.Datetime.now(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') update_by = self._context.get('update_by') diff --git a/indoteknik_custom/views/automatic_purchase.xml b/indoteknik_custom/views/automatic_purchase.xml index 0478304e..245fda90 100644 --- a/indoteknik_custom/views/automatic_purchase.xml +++ b/indoteknik_custom/views/automatic_purchase.xml @@ -22,6 +22,7 @@ + -- cgit v1.2.3 From 2781fdc5b7ce06ef1a68258b96956856bae18519 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 24 Jan 2024 10:34:03 +0700 Subject: fix sale monitoring detail query --- indoteknik_custom/models/sale_monitoring_detail.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_monitoring_detail.py b/indoteknik_custom/models/sale_monitoring_detail.py index ef2c832f..8c35b1cc 100755 --- a/indoteknik_custom/models/sale_monitoring_detail.py +++ b/indoteknik_custom/models/sale_monitoring_detail.py @@ -25,6 +25,16 @@ class SaleMonitoringDetail(models.Model): note = fields.Char(string="Note") vendor_id = fields.Many2one('res.partner', string='Vendor') + def _compute_vendor(self): + for r in self: + sale_lines = self.env['sale.order.line'].search([ + ('order_id', '=', r.sale_order_id.id), + ('product_id', '=', r.product_id.id), + ]) + + for line in sale_lines: + r.vendor_id = line.vendor_id.id + def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(""" @@ -55,8 +65,8 @@ class SaleMonitoringDetail(models.Model): get_qty_po(so.id, sol.product_id) AS qty_po, get_qty_received(so.id, sol.product_id) AS qty_po_received, get_qty_reserved(so.id, sol.product_id) as qty_reserved, - get_vendor_id(so.id, sol.product_id) as vendor_id, - sol.note_procurement as note + sol.note_procurement as note, + sol.vendor_id as vendor_id FROM sale_order so JOIN sale_order_line sol ON sol.order_id = so.id JOIN product_product p ON p.id = sol.product_id -- cgit v1.2.3 From abcb1dbdfd8f5443f6f331aeee1ab5f66c04670f Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 24 Jan 2024 11:26:14 +0700 Subject: add new due date to tree invoice --- indoteknik_custom/views/account_move.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index ddd266bb..126a7a69 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -63,6 +63,7 @@ invoice_day_to_due < 0 + Date: Wed, 24 Jan 2024 12:00:12 +0700 Subject: status printed di sj --- indoteknik_custom/models/purchase_order.py | 4 ++-- indoteknik_custom/models/stock_picking.py | 4 ++++ indoteknik_custom/views/stock_picking.xml | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index ebadff06..984c8a23 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -302,9 +302,9 @@ class PurchaseOrder(models.Model): res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() - if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: + if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager or not self.env.user.is_leader: raise UserError("Beda Margin dengan Sales, harus approval Manager") - if not self.sale_order_id and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: + if not self.sale_order_id and not self.env.user.is_purchasing_manager or not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Manager") send_email = False self.add_product_to_pricelist() diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 2819d6e7..40c8c1f9 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -76,6 +76,10 @@ class StockPicking(models.Model): carrier_id = fields.Many2one('delivery.carrier', string='Shipping Method') shipping_status = fields.Char(string='Shipping Status', compute="_compute_shipping_status") date_reserved = fields.Datetime(string="Date Reserved", help='Tanggal ter-reserved semua barang nya') + status_printed = fields.Selection([ + ('not_printed', 'Belum Print'), + ('printed', 'Printed') + ], string='Printed SJ?', copy=False) def _compute_shipping_status(self): for rec in self: diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index b0932d5a..979bede3 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -19,6 +19,7 @@ + @@ -59,6 +60,7 @@ + -- cgit v1.2.3 From ac4337e441fbd575ac8c0a5f43ae77b7e8fbc328 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 24 Jan 2024 14:52:19 +0700 Subject: add optional hide --- indoteknik_custom/views/account_move.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 126a7a69..449a048d 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -63,7 +63,7 @@ invoice_day_to_due < 0 - + Date: Wed, 24 Jan 2024 16:06:32 +0700 Subject: add new field to account move --- indoteknik_custom/models/account_move.py | 5 +++++ indoteknik_custom/models/purchase_order.py | 4 ++-- indoteknik_custom/views/account_move.xml | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index ae09d0ee..948f6e62 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -37,6 +37,7 @@ class AccountMove(models.Model): ], 'Mark Upload Faktur', compute='_compute_mark_upload_efaktur', default='belum_upload') sale_id = fields.Many2one('sale.order', string='Sale Order') reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('partner_id', '=', partner_id)]") + new_invoice_day_to_due = fields.Integer(string="New Day Due", compute="_compute_invoice_day_to_due") def open_form_multi_create_reklas_penjualan(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_view_invoice_reklas_penjualan') @@ -132,12 +133,16 @@ class AccountMove(models.Model): def _compute_invoice_day_to_due(self): for invoice in self: invoice_day_to_due = 0 + new_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() + new_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 + new_invoice_day_to_due = new_invoice_day_to_due.days invoice.invoice_day_to_due = invoice_day_to_due + invoice.new_invoice_day_to_due = new_invoice_day_to_due def _compute_bill_day_to_due(self): for rec in self: diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 984c8a23..ebadff06 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -302,9 +302,9 @@ class PurchaseOrder(models.Model): res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() - if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager or not self.env.user.is_leader: + if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: raise UserError("Beda Margin dengan Sales, harus approval Manager") - if not self.sale_order_id and not self.env.user.is_purchasing_manager or not self.env.user.is_leader: + if not self.sale_order_id and not self.env.user.is_purchasing_manager and not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Manager") send_email = False self.add_product_to_pricelist() diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 449a048d..677a1d99 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -64,7 +64,8 @@ - + + -- cgit v1.2.3 From ab11e1060a839b5cbd13b56e98fa291cc6a74e38 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 25 Jan 2024 13:18:47 +0700 Subject: add tracking to unreserved and check_availability button --- indoteknik_custom/models/stock_picking.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 40c8c1f9..6754ebab 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -80,6 +80,14 @@ class StockPicking(models.Model): ('not_printed', 'Belum Print'), ('printed', 'Printed') ], string='Printed SJ?', copy=False) + date_unreserve = fields.Datetime(string="Date Unreserved", copy=False, tracking=True) + date_availability = fields.Datetime(string="Date Availability", copy=False, tracking=True) + + def do_unreserve(self): + res = super(StockPicking, self).do_unreserve() + current_time = datetime.datetime.utcnow() + self.date_unreserve = current_time + return res def _compute_shipping_status(self): for rec in self: @@ -204,7 +212,9 @@ class StockPicking(models.Model): def action_assign(self): res = super(StockPicking, self).action_assign() + current_time = datetime.datetime.utcnow() self.real_shipping_id = self.sale_id.real_shipping_id + self.date_availability = current_time return res def ask_approval(self): -- cgit v1.2.3 From 10eaf6d0c0a0ebf02030fe0854ca51f22fd3795e Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 25 Jan 2024 13:36:02 +0700 Subject: Update image watermark --- indoteknik_api/controllers/controller.py | 4 ++-- .../static/src/images/logo-indoteknik.png | Bin 29443 -> 29514 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 36f5aa9b..a3fb6fcb 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -213,9 +213,9 @@ class Controller(http.Controller): img = img.convert('RGBA') img_width, img_height = img.size - logo_img.thumbnail((img_width // 3, img_height // 3)) + logo_img.thumbnail((img_width // 2.2, img_height // 2.2)) - img.paste(logo_img, (20, 15), logo_img) + img.paste(logo_img, (12, 10), logo_img) buffered = io.BytesIO() img.save(buffered, format="PNG") diff --git a/indoteknik_api/static/src/images/logo-indoteknik.png b/indoteknik_api/static/src/images/logo-indoteknik.png index 0770c265..3039ca38 100644 Binary files a/indoteknik_api/static/src/images/logo-indoteknik.png and b/indoteknik_api/static/src/images/logo-indoteknik.png differ -- cgit v1.2.3 From 0afeff9478a7aea67fbf3abed936390571aae788 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 25 Jan 2024 13:47:05 +0700 Subject: Add model with watermark on image api --- indoteknik_api/controllers/controller.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index a3fb6fcb..7ceebbe3 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -186,11 +186,14 @@ class Controller(http.Controller): @http.route('/api/image///', auth='public', methods=['GET']) def get_image(self, model, field, id, **kw): + model_name = model + model = request.env[model].sudo().search([('id', '=', id)], limit=1) image = model[field] if model[field] else '' + model_with_watermark = ['product.template', 'product.product'] watermark = kw.get('watermark', '') - if watermark.lower() == 'true': + if watermark.lower() == 'true' or model_name in model_with_watermark: image = self.add_watermark_to_image(image) response_headers = [ -- cgit v1.2.3 From 19fa8e951da70347d822bb5b0f2acf5563afc704 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 25 Jan 2024 14:52:15 +0700 Subject: Add square ratio on image api --- indoteknik_api/controllers/controller.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 7ceebbe3..bd763e00 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -194,7 +194,8 @@ class Controller(http.Controller): model_with_watermark = ['product.template', 'product.product'] watermark = kw.get('watermark', '') if watermark.lower() == 'true' or model_name in model_with_watermark: - image = self.add_watermark_to_image(image) + ratio = kw.get('ratio', '') + image = self.add_watermark_to_image(image, ratio) response_headers = [ ('Content-Type', 'image/jpg'), @@ -206,7 +207,7 @@ class Controller(http.Controller): response_headers ) - def add_watermark_to_image(self, image): + def add_watermark_to_image(self, image, ratio): logo_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', 'logo-indoteknik.png') logo_img = Image.open(logo_path) logo_img = logo_img.convert('RGBA') @@ -217,10 +218,23 @@ class Controller(http.Controller): img_width, img_height = img.size logo_img.thumbnail((img_width // 2.2, img_height // 2.2)) + + new_img = img + + if ratio == 'square': + longest_wh = max(img_height, img_width) - img.paste(logo_img, (12, 10), logo_img) + new_img = Image.new('RGBA', (longest_wh, longest_wh), (255, 255, 255, 255)) + + paste_x = (longest_wh - img_width) // 2 + paste_y = (longest_wh - img_height) // 2 + + new_img.paste(img, (paste_x, paste_y), img) + + # Add watermark + new_img.paste(logo_img, (12, 10), logo_img) buffered = io.BytesIO() - img.save(buffered, format="PNG") + new_img.save(buffered, format="PNG") return base64.b64encode(buffered.getvalue()).decode('utf-8') -- cgit v1.2.3 From bf84a6df71756afdd4b8846b8bba8fea4d243dee Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 25 Jan 2024 16:04:03 +0700 Subject: add field date_upload_efaktur on invoices --- indoteknik_custom/models/account_move.py | 7 +++++++ indoteknik_custom/views/account_move.xml | 1 + 2 files changed, 8 insertions(+) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 948f6e62..592a3ae7 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -38,6 +38,13 @@ class AccountMove(models.Model): sale_id = fields.Many2one('sale.order', string='Sale Order') reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('partner_id', '=', partner_id)]") new_invoice_day_to_due = fields.Integer(string="New Day Due", compute="_compute_invoice_day_to_due") + date_efaktur_upload = fields.Datetime(string='eFaktur Upload Date') + + @api.constrains('efaktur_document') + def _constrains_date_efaktur(self): + for move in self: + current_time = datetime.utcnow() + move.date_efaktur_upload = current_time def open_form_multi_create_reklas_penjualan(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_view_invoice_reklas_penjualan') diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 677a1d99..a7d339ce 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -25,6 +25,7 @@ + pdf_viewer -- cgit v1.2.3 From 8a63e82659a9a718b0dfeba0423a037130e57acd Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 25 Jan 2024 16:07:57 +0700 Subject: readonly field --- indoteknik_custom/views/account_move.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index a7d339ce..97951b95 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -25,7 +25,7 @@ - + pdf_viewer -- cgit v1.2.3 From eaa709aaa938b142fa7ea2179dc915b0a5b71ad3 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 26 Jan 2024 11:38:59 +0700 Subject: add tracking on field date_efaktur_upload --- indoteknik_custom/models/account_move.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 592a3ae7..a9db212f 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -38,7 +38,7 @@ class AccountMove(models.Model): sale_id = fields.Many2one('sale.order', string='Sale Order') reklas_id = fields.Many2one('account.move', string='Nomor CAB', domain="[('partner_id', '=', partner_id)]") new_invoice_day_to_due = fields.Integer(string="New Day Due", compute="_compute_invoice_day_to_due") - date_efaktur_upload = fields.Datetime(string='eFaktur Upload Date') + date_efaktur_upload = fields.Datetime(string='eFaktur Upload Date', tracking=True) @api.constrains('efaktur_document') def _constrains_date_efaktur(self): -- cgit v1.2.3 From ffd0720dcf8e1cea03ac2b02afa12910d8bd3fe8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 26 Jan 2024 11:48:32 +0700 Subject: fix error sale order sync --- indoteknik_custom/models/purchase_order_line.py | 32 +++++++++++-------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index c7da0e24..f4995b16 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -2,6 +2,7 @@ from odoo import fields, models, api, _ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT import logging +from datetime import datetime _logger = logging.getLogger(__name__) @@ -103,24 +104,19 @@ class PurchaseOrderLine(models.Model): return res def _get_valid_purchase_price(self, purchase_price): - p_price = 0 - taxes = False - - if purchase_price.system_price > 0 and purchase_price.product_price > 0: - if purchase_price.human_last_update > purchase_price.system_last_update: - p_price = purchase_price.product_price - taxes = purchase_price.taxes_product_id - else: - p_price = purchase_price.system_price - taxes = purchase_price.taxes_system_id - elif purchase_price.system_price > 0 and purchase_price.product_price == 0: - p_price = purchase_price.system_price - taxes = purchase_price.taxes_system_id - elif purchase_price.system_price == 0 and purchase_price.product_price > 0: - p_price = purchase_price.product_price - taxes = purchase_price.taxes_product_id - - return p_price, taxes + price = 0 + taxes = None + human_last_update = purchase_price.human_last_update or datetime.min + system_last_update = purchase_price.system_last_update or datetime.min + + if system_last_update > human_last_update: + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id + else: + price = purchase_price.product_price + taxes = [purchase.taxes_product_id.id for purchase in purchase_price ] + + return price, taxes def compute_item_margin(self): sum_so_margin = sum_sales_price = sum_margin = 0 -- cgit v1.2.3 From d331e26d7149bf62629c62f01994fd7a285da0c3 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 26 Jan 2024 11:48:32 +0700 Subject: fix error sale order sync --- indoteknik_custom/models/purchase_order_line.py | 32 +++++++++++-------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index c7da0e24..465944d5 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -2,6 +2,7 @@ from odoo import fields, models, api, _ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT import logging +from datetime import datetime _logger = logging.getLogger(__name__) @@ -103,24 +104,19 @@ class PurchaseOrderLine(models.Model): return res def _get_valid_purchase_price(self, purchase_price): - p_price = 0 - taxes = False - - if purchase_price.system_price > 0 and purchase_price.product_price > 0: - if purchase_price.human_last_update > purchase_price.system_last_update: - p_price = purchase_price.product_price - taxes = purchase_price.taxes_product_id - else: - p_price = purchase_price.system_price - taxes = purchase_price.taxes_system_id - elif purchase_price.system_price > 0 and purchase_price.product_price == 0: - p_price = purchase_price.system_price - taxes = purchase_price.taxes_system_id - elif purchase_price.system_price == 0 and purchase_price.product_price > 0: - p_price = purchase_price.product_price - taxes = purchase_price.taxes_product_id - - return p_price, taxes + price = 0 + taxes = None + human_last_update = purchase_price.human_last_update or datetime.min + system_last_update = purchase_price.system_last_update or datetime.min + + if system_last_update > human_last_update: + price = purchase_price.system_price + taxes = [purchase.taxes_system_id.id for purchase in purchase_price ] + else: + price = purchase_price.product_price + taxes = [purchase.taxes_product_id.id for purchase in purchase_price ] + + return price, taxes def compute_item_margin(self): sum_so_margin = sum_sales_price = sum_margin = 0 -- cgit v1.2.3 From 8bb31d4a2f2c3037dad4acf8a8f280f9581b5d34 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 26 Jan 2024 15:12:17 +0700 Subject: fix bug include_price --- indoteknik_custom/models/purchase_pricelist.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index c756c301..805ebc89 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -34,7 +34,11 @@ class PurchasePricelist(models.Model): @api.constrains('system_last_update','system_price','product_price','human_last_update','taxes_system_id','taxes_product_id') def _contrains_include_price(self): + price_unit, taxes = self._get_valid_price() + if price_unit == 0: + self.include_price = 0 + return # taxes = self.taxes_system_id or self.taxes_product_id # price_unit = self.system_price or self.product_price tax_include = taxes.price_include -- cgit v1.2.3 From bbbb683a01e316633cdbe8ef82303d05562ae0bb Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 29 Jan 2024 09:57:32 +0700 Subject: change name field on stock picking --- indoteknik_custom/models/stock_picking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 6754ebab..1c58d954 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -79,7 +79,7 @@ class StockPicking(models.Model): status_printed = fields.Selection([ ('not_printed', 'Belum Print'), ('printed', 'Printed') - ], string='Printed SJ?', copy=False) + ], string='Printed?', copy=False) date_unreserve = fields.Datetime(string="Date Unreserved", copy=False, tracking=True) date_availability = fields.Datetime(string="Date Availability", copy=False, tracking=True) -- cgit v1.2.3 From 2fa8a1e7b1e8e48cb241e9cd7198a423ad6f172d Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 29 Jan 2024 11:13:40 +0700 Subject: Update import restriction feature --- indoteknik_custom/models/base_import_import.py | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/indoteknik_custom/models/base_import_import.py b/indoteknik_custom/models/base_import_import.py index 9cffa6e6..bc3b0e37 100644 --- a/indoteknik_custom/models/base_import_import.py +++ b/indoteknik_custom/models/base_import_import.py @@ -1,6 +1,8 @@ +from datetime import datetime + from odoo import models from odoo.exceptions import UserError -from datetime import datetime + class Import(models.TransientModel): _inherit = 'base_import.import' @@ -8,8 +10,8 @@ class Import(models.TransientModel): def _get_config_enable_import(self): return self.env['ir.config_parameter'].sudo().get_param('base_import.import.enable_import', '') - def _get_config_restrict_model(self): - return self.env['ir.config_parameter'].sudo().get_param('base_import.import.restrict_model', '') + def _get_config_allowed_model(self): + return self.env['ir.config_parameter'].sudo().get_param('base_import.import.allowed_model', '') def _check_time_range(self, config_string): current_time = datetime.now().time() @@ -27,19 +29,20 @@ class Import(models.TransientModel): def _check_enable_import(self): enable_import = self._get_config_enable_import() - restrict_model = self._get_config_restrict_model() - - if self.res_model not in restrict_model: - return True + allowed_model = self._get_config_allowed_model() - if enable_import.lower() == 'true': - return True - elif enable_import.lower() == 'false': + is_allowed = False + if (allowed_model != '-' and self.res_model in allowed_model) or allowed_model == 'ALL': + is_allowed = True + + if enable_import.lower() == 'false': return False - elif '-' in enable_import: + elif enable_import.lower() == 'true' and is_allowed: + return True + elif '-' in enable_import and is_allowed: return self._check_time_range(enable_import) - return True + return False def _unable_import_notif(self): enable_import_config = self._get_config_enable_import() -- cgit v1.2.3 From a08c05d892dc01cad4acaa24c7e1eab16f4a9639 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 29 Jan 2024 11:53:27 +0700 Subject: Update image watermark --- indoteknik_api/controllers/controller.py | 65 +++++++++++++-------- .../static/src/images/logo-indoteknik-footer.png | Bin 0 -> 17722 bytes .../static/src/images/logo-indoteknik-gray.png | Bin 0 -> 29514 bytes .../static/src/images/logo-indoteknik.png | Bin 29514 -> 33475 bytes 4 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 indoteknik_api/static/src/images/logo-indoteknik-footer.png create mode 100644 indoteknik_api/static/src/images/logo-indoteknik-gray.png diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index bd763e00..fb07708e 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -1,17 +1,17 @@ -from array import array -import datetime import base64 +import datetime +import functools +import io import json +from array import array -from odoo import http, tools +import jwt +from odoo import http from odoo.http import request -from odoo.tools.config import config from odoo.modules import get_module_resource +from odoo.tools.config import config +from PIL import Image from pytz import timezone -from PIL import Image, ImageDraw, ImageFont -import jwt -import functools -import io class Controller(http.Controller): @@ -187,15 +187,14 @@ class Controller(http.Controller): @http.route('/api/image///', auth='public', methods=['GET']) def get_image(self, model, field, id, **kw): model_name = model - model = request.env[model].sudo().search([('id', '=', id)], limit=1) - image = model[field] if model[field] else '' + image = model[field] if field in model else '' - model_with_watermark = ['product.template', 'product.product'] - watermark = kw.get('watermark', '') - if watermark.lower() == 'true' or model_name in model_with_watermark: + if model_name in ['product.template', 'product.product']: + version = '2' if field not in ['image_256', 'image_512', 'image_1024', 'image_1920'] else '1' ratio = kw.get('ratio', '') - image = self.add_watermark_to_image(image, ratio) + image = model['image_512'] or '' + image = self.add_watermark_to_image(image, ratio, version) response_headers = [ ('Content-Type', 'image/jpg'), @@ -207,29 +206,49 @@ class Controller(http.Controller): response_headers ) - def add_watermark_to_image(self, image, ratio): - logo_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', 'logo-indoteknik.png') - logo_img = Image.open(logo_path) - logo_img = logo_img.convert('RGBA') + + def add_watermark_to_image(self, image, ratio, version = '1'): + if not image: return '' + + LOGO_FILENAME = { + '1': 'logo-indoteknik-gray.png', + '2': 'logo-indoteknik.png' + } + + logo_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', LOGO_FILENAME.get(version)) + logo_img = Image.open(logo_path).convert('RGBA') img_data = io.BytesIO(base64.b64decode(image)) - img = Image.open(img_data) - img = img.convert('RGBA') + img = Image.open(img_data).convert('RGBA') img_width, img_height = img.size - logo_img.thumbnail((img_width // 2.2, img_height // 2.2)) + longest_wh = max(img_height, img_width) + + # Resize logo image + logo_img_w = img_width // 2.2 + logo_img_h = img_height // 2.2 new_img = img + if version == '2': + logo__footer_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', 'logo-indoteknik-footer.png') + logo__footer_img = Image.open(logo__footer_path).convert('RGBA') + logo__footer_img.thumbnail((img_width, img_height // 1)) + logo_footer_w, logo_footer_h = logo__footer_img.size + new_img.paste(logo__footer_img, (0, img_height - logo_footer_h), logo__footer_img) + + logo_img_w = img_width // 1.8 + logo_img_h = img_height // 1.8 + if ratio == 'square': - longest_wh = max(img_height, img_width) - new_img = Image.new('RGBA', (longest_wh, longest_wh), (255, 255, 255, 255)) paste_x = (longest_wh - img_width) // 2 paste_y = (longest_wh - img_height) // 2 new_img.paste(img, (paste_x, paste_y), img) + + logo_img.thumbnail((logo_img_w, logo_img_h)) # Add watermark new_img.paste(logo_img, (12, 10), logo_img) diff --git a/indoteknik_api/static/src/images/logo-indoteknik-footer.png b/indoteknik_api/static/src/images/logo-indoteknik-footer.png new file mode 100644 index 00000000..4ebda906 Binary files /dev/null and b/indoteknik_api/static/src/images/logo-indoteknik-footer.png differ diff --git a/indoteknik_api/static/src/images/logo-indoteknik-gray.png b/indoteknik_api/static/src/images/logo-indoteknik-gray.png new file mode 100644 index 00000000..3039ca38 Binary files /dev/null and b/indoteknik_api/static/src/images/logo-indoteknik-gray.png differ diff --git a/indoteknik_api/static/src/images/logo-indoteknik.png b/indoteknik_api/static/src/images/logo-indoteknik.png index 3039ca38..e669699c 100644 Binary files a/indoteknik_api/static/src/images/logo-indoteknik.png and b/indoteknik_api/static/src/images/logo-indoteknik.png differ -- cgit v1.2.3 From a142137887530c904c158859889f340c42fe78e1 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Mon, 29 Jan 2024 13:45:45 +0700 Subject: refactor kode validation duplicate product --- indoteknik_custom/models/product_template.py | 92 +++++++++++++++------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index bdbc391d..30d89356 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -74,32 +74,34 @@ class ProductTemplate(models.Model): @api.constrains('name', 'default_code') def _check_duplicate_product(self): for product in self: - if not self.env.user.is_purchasing_manager and not self.env.user.is_editor_product and self.env.user.id not in [1, 25]: - domain = [('default_code', '!=', False)] - - if product.product_variant_ids: - domain.extend([ - '|', - ('name', 'in', [variants.name for variants in product.product_variant_ids]), - ('default_code', 'in', [variants.default_code for variants in product.product_variant_ids]) - ]) - else: - domain.extend([ - '|', - ('name', 'in', [product.name]), - ('default_code', 'in', [product.default_code]) - ]) - - domain.append(('id', '!=', product.id)) - - if product.write_date == product.create_date: - message = "SKU atau Name yang Anda gunakan sudah digunakan di produk lain" - elif all(day_product > 0 for day_product in product.day_product_to_edit()): - domain = [('id', '=', product.id)] - message = "Hanya Pak Tyas yang dapat merubah data produk" - existing_purchase = self.search(domain, limit=1) - if existing_purchase: - raise UserError(message) + if self.env.user.is_purchasing_manager or self.env.user.is_editor_product or self.env.user.id in [1, 25]: + continue + + domain = [('default_code', '!=', False)] + + if product.product_variant_ids: + domain.extend([ + '|', + ('name', 'in', [variants.name for variants in product.product_variant_ids]), + ('default_code', 'in', [variants.default_code for variants in product.product_variant_ids]) + ]) + else: + domain.extend([ + '|', + ('name', 'in', [product.name]), + ('default_code', 'in', [product.default_code]) + ]) + + domain.append(('id', '!=', product.id)) + + if product.write_date == product.create_date: + message = "SKU atau Name yang Anda gunakan sudah digunakan di produk lain" + elif all(day_product > 0 for day_product in product.day_product_to_edit()): + domain = [('id', '=', product.id)] + message = "Anda tidak berhak merubah data produk ini" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(message) @api.constrains('name') def _validate_name(self): @@ -379,24 +381,26 @@ class ProductProduct(models.Model): @api.constrains('name','default_code') def _check_duplicate_product(self): for product in self: - if not self.env.user.is_purchasing_manager and not self.env.user.is_editor_product and self.env.user.id not in [1, 25]: - if product.write_date == product.create_date: - domain = [ - ('default_code', '!=', False), - '|', - ('name', 'in', [template.name for template in product.product_tmpl_id] or [product.name]), - ('default_code', 'in', [template.default_code for template in product.product_tmpl_id] or [product.default_code])] - - domain.append(('id', '!=', product.id)) - massage="SKU atau Name yang anda pakai sudah digunakan di product lain" - existing_purchase = self.search(domain, limit=1) - if existing_purchase: - raise UserError(massage) - elif all(day_product > 0 for day_product in product.day_product_to_edit()): - domain = [('id', '=', product.id)] - existing_purchase = self.search(domain) - if existing_purchase: - raise UserError('Hanya Pak Tyas Yang Dapat Merubah Data Product') + if self.env.user.is_purchasing_manager or self.env.user.is_editor_product or self.env.user.id in [1, 25]: + continue + + if product.write_date == product.create_date: + domain = [ + ('default_code', '!=', False), + '|', + ('name', 'in', [template.name for template in product.product_tmpl_id] or [product.name]), + ('default_code', 'in', [template.default_code for template in product.product_tmpl_id] or [product.default_code])] + + domain.append(('id', '!=', product.id)) + massage="SKU atau Name yang anda pakai sudah digunakan di product lain" + existing_purchase = self.search(domain, limit=1) + if existing_purchase: + raise UserError(massage) + elif all(day_product > 0 for day_product in product.day_product_to_edit()): + domain = [('id', '=', product.id)] + existing_purchase = self.search(domain) + if existing_purchase: + raise UserError('Anda tidak berhak merubah data product ini') @api.constrains('name') def _validate_name(self): -- cgit v1.2.3 From 4a35b0d5432ed38395fa8f8cb6ebcfb5e0887f28 Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Mon, 29 Jan 2024 14:26:20 +0700 Subject: add status note logistc --- indoteknik_custom/models/stock_picking.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 6754ebab..8ff782ba 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -69,7 +69,9 @@ class StockPicking(models.Model): note_logistic = fields.Selection([ ('hold', 'Hold by Sales'), ('not_paid', 'Customer belum bayar'), - ('partial', 'Kirim Parsial') + ('partial', 'Kirim Parsial'), + ('not_complete', 'Belum Lengkap'), + ('indent', 'Indent') ], string='Note Logistic', help='jika field ini diisi maka tidak akan dihitung ke lead time') waybill_id = fields.One2many(comodel_name='airway.bill', inverse_name='do_id', string='Airway Bill') purchase_representative_id = fields.Many2one('res.users', related='move_lines.purchase_line_id.order_id.user_id', string="Purchase Representative", readonly=True) -- cgit v1.2.3 From 9c3ba66d67a91a3281f8fcb2c4956f69489600ab Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 29 Jan 2024 16:04:47 +0700 Subject: Update import setting feature --- indoteknik_api/controllers/controller.py | 2 +- indoteknik_custom/models/base_import_import.py | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index fb07708e..bb060cf5 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -191,7 +191,7 @@ class Controller(http.Controller): image = model[field] if field in model else '' if model_name in ['product.template', 'product.product']: - version = '2' if field not in ['image_256', 'image_512', 'image_1024', 'image_1920'] else '1' + version = '1' if field in ['image_256', 'image_512', 'image_1024', 'image_1920'] else '2' ratio = kw.get('ratio', '') image = model['image_512'] or '' image = self.add_watermark_to_image(image, ratio, version) diff --git a/indoteknik_custom/models/base_import_import.py b/indoteknik_custom/models/base_import_import.py index bc3b0e37..043f860c 100644 --- a/indoteknik_custom/models/base_import_import.py +++ b/indoteknik_custom/models/base_import_import.py @@ -2,6 +2,7 @@ from datetime import datetime from odoo import models from odoo.exceptions import UserError +from pytz import timezone class Import(models.TransientModel): @@ -12,17 +13,21 @@ class Import(models.TransientModel): def _get_config_allowed_model(self): return self.env['ir.config_parameter'].sudo().get_param('base_import.import.allowed_model', '') + + def _get_config_always_allowed_model(self): + return self.env['ir.config_parameter'].sudo().get_param('base_import.import.always_allowed_model', '') def _check_time_range(self, config_string): - current_time = datetime.now().time() + current_time = datetime.now(tz=timezone('Asia/Jakarta')).time() ranges = config_string.split(' / ') for time_range in ranges: start_str, end_str = time_range.split(' - ') start_time = datetime.strptime(start_str, '%H:%M:%S').time() end_time = datetime.strptime(end_str, '%H:%M:%S').time() - - if start_time <= current_time and current_time <= end_time: + + # If current time in range of start and end time + if current_time >= start_time and current_time <= end_time: return True return False @@ -30,16 +35,12 @@ class Import(models.TransientModel): def _check_enable_import(self): enable_import = self._get_config_enable_import() allowed_model = self._get_config_allowed_model() + always_allowed_model = self._get_config_always_allowed_model() - is_allowed = False - if (allowed_model != '-' and self.res_model in allowed_model) or allowed_model == 'ALL': - is_allowed = True - - if enable_import.lower() == 'false': - return False - elif enable_import.lower() == 'true' and is_allowed: + if self.res_model in always_allowed_model or always_allowed_model == 'ALL': return True - elif '-' in enable_import and is_allowed: + + if self.res_model in allowed_model or allowed_model == 'ALL': return self._check_time_range(enable_import) return False -- cgit v1.2.3 From b2de86fc46f09c14e415181496bee38733d50306 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 30 Jan 2024 14:11:38 +0700 Subject: update image api source size --- indoteknik_api/controllers/controller.py | 2 +- indoteknik_custom/models/base_import_import.py | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index bb060cf5..0592afe1 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -193,7 +193,7 @@ class Controller(http.Controller): if model_name in ['product.template', 'product.product']: version = '1' if field in ['image_256', 'image_512', 'image_1024', 'image_1920'] else '2' ratio = kw.get('ratio', '') - image = model['image_512'] or '' + image = model['image_256'] or '' image = self.add_watermark_to_image(image, ratio, version) response_headers = [ diff --git a/indoteknik_custom/models/base_import_import.py b/indoteknik_custom/models/base_import_import.py index 043f860c..6a100cb8 100644 --- a/indoteknik_custom/models/base_import_import.py +++ b/indoteknik_custom/models/base_import_import.py @@ -7,15 +7,18 @@ from pytz import timezone class Import(models.TransientModel): _inherit = 'base_import.import' + + def _get_config(self, key, default = ''): + return self.env['ir.config_parameter'].sudo().get_param('base_import.import.' + key, default) def _get_config_enable_import(self): - return self.env['ir.config_parameter'].sudo().get_param('base_import.import.enable_import', '') + return self._get_config('enable_import') def _get_config_allowed_model(self): - return self.env['ir.config_parameter'].sudo().get_param('base_import.import.allowed_model', '') + return self._get_config('allowed_model') def _get_config_always_allowed_model(self): - return self.env['ir.config_parameter'].sudo().get_param('base_import.import.always_allowed_model', '') + return self._get_config('always_allowed_model') def _check_time_range(self, config_string): current_time = datetime.now(tz=timezone('Asia/Jakarta')).time() -- cgit v1.2.3 From 5e3e425902513c9a013f208c9e374ea322e516c3 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 31 Jan 2024 10:14:58 +0700 Subject: Add image on product variant --- indoteknik_custom/models/solr/product_product.py | 13 +++++++------ indoteknik_custom/models/solr/product_template.py | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index fe2a08dc..6a0073bd 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -1,6 +1,7 @@ -from odoo import models, fields, api from datetime import datetime +from odoo import api, fields, models + class ProductProduct(models.Model): _inherit = 'product.product' @@ -37,15 +38,14 @@ class ProductProduct(models.Model): def _sync_variants_to_solr(self): solr_model = self.env['apache.solr'] + ir_attachment = self.env['ir.attachment'] for variant in self: - category_id = 0 category_name = '' for category in variant.product_tmpl_id.public_categ_ids: category_id = category.id category_name = category.name - break document = solr_model.get_doc('variants', variant.id) document.update({ @@ -56,14 +56,15 @@ class ProductProduct(models.Model): 'product_rating_f': variant.product_tmpl_id.virtual_rating, 'product_id_i': variant.id, 'template_id_i': variant.product_tmpl_id.id, - 'image_s': self.env['ir.attachment'].api_image('product.template', 'image_512', variant.product_tmpl_id.id), + "image_s": ir_attachment.api_image('product.product', 'image_256', variant.id), + 'parent_image_s': ir_attachment.api_image('product.template', 'image_256', variant.product_tmpl_id.id), 'stock_total_f': variant.qty_stock_vendor, 'weight_f': variant.product_tmpl_id.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, 'manufacture_name_s': variant.product_tmpl_id.x_manufacture.x_name or '', 'manufacture_name': variant.product_tmpl_id.x_manufacture.x_name or '', - 'image_promotion_1_s': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_1', variant.product_tmpl_id.x_manufacture.id), - 'image_promotion_2_s': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_2', variant.product_tmpl_id.x_manufacture.id), + 'image_promotion_1_s': ir_attachment.api_image('x_manufactures', 'image_promotion_1', variant.product_tmpl_id.x_manufacture.id), + 'image_promotion_2_s': ir_attachment.api_image('x_manufactures', 'image_promotion_2', variant.product_tmpl_id.x_manufacture.id), 'category_id_i': category_id, 'category_name_s': category_name, 'category_name': category_name, diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index bba98edc..062f1455 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -1,6 +1,7 @@ -from odoo import models, fields, api from datetime import datetime +from odoo import api, fields, models + class ProductTemplate(models.Model): _inherit = "product.template" @@ -70,7 +71,7 @@ class ProductTemplate(models.Model): "default_code_s": template.default_code or '', "product_rating_f": template.virtual_rating, "product_id_i": template.id, - "image_s": self.env['ir.attachment'].api_image('product.template', 'image_512', template.id), + "image_s": self.env['ir.attachment'].api_image('product.template', 'image_256', template.id), "variant_total_i": template.product_variant_count, "stock_total_f": template.qty_stock_vendor, "weight_f": template.weight, -- cgit v1.2.3 From 1f491c22d519edb0df0515eba803dcd2a3436cf8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 31 Jan 2024 16:19:39 +0700 Subject: fix error local variable assignment --- indoteknik_custom/models/requisition.py | 227 ++++++++++++++++---------------- 1 file changed, 111 insertions(+), 116 deletions(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 7ceff6e5..d6b33044 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -1,6 +1,7 @@ -from odoo import models, fields, api +from odoo import models, fields, api, _ from odoo.exceptions import UserError from datetime import datetime +import math import logging _logger = logging.getLogger(__name__) @@ -28,108 +29,84 @@ class Requisition(models.Model): result = super(Requisition, self).create(vals) return result - # def create_requisition_from_sales_with_price(self): - # if self.requisition_lines: - # raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu') - # if not self.sale_order_id: - # raise UserError('Sale Order harus diisi') - # if self.is_po: - # raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya') - - # count = 0 - # for order_line in self.sale_order_id.order_line: - # # get purchase price altama, if nothing, then get other cheaper, if nothing then last po - # purchase_price = order_line.purchase_price - # vendor_id = order_line.vendor_id.id - - # # get qty available bandengan - # qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty - # suggest = 'harus beli' - # if qty_available > order_line.product_qty: - # suggest = 'masih cukup' - - # self.env['requisition.line'].create([{ - # 'requisition_id': self.id, - # 'partner_id': vendor_id, - # 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id, - # 'product_id': order_line.product_id.id, - # 'qty_purchase': order_line.product_uom_qty, - # 'tax_id': order_line.purchase_tax_id.id, - # 'price_unit': purchase_price, - # 'subtotal': purchase_price * order_line.product_uom_qty, - # 'source': 'sales', - # 'qty_available_store': qty_available, - # 'suggest': suggest, - # }]) - # count+=1 - # _logger.info('Create Requisition %s' % order_line.product_id.name) - # self.notification = "Requisition Created %s lines" % count - - # def create_requisition_from_sales(self): - # if self.requisition_lines: - # raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu') - # if not self.sale_order_id: - # raise UserError('Sale Order harus diisi') - # if self.is_po: - # raise UserError('Sudah jadi PO, tidak bisa di create ulang PO nya') + + def create_po_from_requisition(self): + if not self.requisition_lines: + raise UserError('Tidak ada Lines, belum bisa create PO') + if self.is_po: + raise UserError('Sudah pernah di create PO') + + vendor_ids = self.env['requisition.line'].read_group([ + ('requisition_id', '=', self.id), + ('partner_id', '!=', False) + ], fields=['partner_id'], groupby=['partner_id']) + + po_ids = [] + for vendor in vendor_ids: + result_po = self.create_po_by_vendor(vendor['partner_id'][0]) + po_ids.append(result_po) + return { + 'name': _('Purchase Order'), + 'view_mode': 'tree,form', + 'res_model': 'purchase.order', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', po_ids)], + } - # # old_requisition = self.env['requisition'].search([('sale_order_id', '=', self.sale_order_id.id)], limit=1) - # # if old_requisition: - # # raise UserError('Sudah pernah jadi Requisition') - - # count = 0 - # for order_line in self.sale_order_id.order_line: - # # get purchase price altama, if nothing, then get other cheaper, if nothing then last po - # purchase_price = 0 - # vendor_id = 0 - - # # get qty available bandengan - # qty_available = order_line.product_id.qty_onhand_bandengan + order_line.product_id.qty_incoming_bandengan - order_line.product_id.outgoing_qty - # suggest = 'harus beli' - # if qty_available > order_line.product_qty: - # suggest = 'masih cukup' - - # purchase_pricelist = self.env['purchase.pricelist'].search([ - # ('product_id.id', '=', order_line.product_id.id), - # ('vendor_id.id', '=', 5571) - # ], order='product_price asc', limit=1) - # purchase_price = purchase_pricelist.product_price - # vendor_id = purchase_pricelist.vendor_id.id - # source = 'PriceList' - - # if not purchase_price or purchase_price <= 0: - # purchase_pricelist = self.env['purchase.pricelist'].search([('product_id', '=', order_line.product_id.id)], order='product_price asc', limit=1) - # purchase_price = purchase_pricelist.product_price - # vendor_id = purchase_pricelist.vendor_id.id - # source = 'PriceList' - - # if not purchase_price or purchase_price <= 0: - # last_po_line = self.env['purchase.order.line'].search([('product_id', '=', order_line.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1) - # purchase_price = last_po_line.price_unit - # vendor_id = last_po_line.order_id.partner_id.id - # source = 'LastPO' - - # if not purchase_price or purchase_price <= 0: - # purchase_price = 0 - # vendor_id = 5571 - # source = 'Nothing' - - # self.env['requisition.line'].create([{ - # 'requisition_id': self.id, - # 'partner_id': vendor_id, - # 'brand_id': order_line.product_id.product_tmpl_id.x_manufacture.id, - # 'product_id': order_line.product_id.id, - # 'qty_purchase': order_line.product_uom_qty, - # 'tax_id': order_line.purchase_tax_id.id, - # 'price_unit': purchase_price, - # 'subtotal': purchase_price * order_line.product_uom_qty, - # 'source': source, - # 'qty_available_store': qty_available, - # 'suggest': suggest, - # }]) - # count+=1 - # _logger.info('Create Requisition %s' % order_line.product_id.name) - # self.notification = "Requisition Created %s lines" % count + def create_po_by_vendor(self, vendor_id): + current_time = datetime.now() + + PRODUCT_PER_PO = 20 + + requisition_line = self.env['requisition.line'] + + param_header = { + 'partner_id': vendor_id, + # 'partner_ref': self.sale_order_id.name, + 'currency_id': 12, + 'user_id': self.env.user.id, + 'company_id': 1, # indoteknik dotcom gemilang + 'picking_type_id': 28, # indoteknik bandengan receipts + 'date_order': current_time, + 'sale_order_id': self.sale_order_id.id, + 'note_description': 'from Purchase Requisition' + } + + domain = [ + ('requisition_id', '=', self.id), + ('partner_id', '=', vendor_id), + ('qty_purchase', '>', 0) + ] + + products_len = requisition_line.search_count(domain) + page = math.ceil(products_len / PRODUCT_PER_PO) + po_ids = [] + # i start from zero (0) + for i in range(page): + new_po = self.env['purchase.order'].create([param_header]) + new_po.name = new_po.name + "/R/" + str(i + 1) + po_ids.append(new_po.id) + lines = requisition_line.search( + domain, + offset=i * PRODUCT_PER_PO, + limit=PRODUCT_PER_PO + ) + tax = [22] + + for line in lines: + product = line.product_id + param_line = { + 'product_id': product.product_id.id, + 'product_qty': product.qty_purchase, + 'product_uom_qty': product.qty_purchase, + 'price_unit': product.price_unit, + 'taxes_id': tax, + } + new_po_line = self.env['purchase.order.line'].create([param_line]) + line.current_po_id = new_po.id + line.current_po_line_id = new_po_line.id + return po_ids def create_po_from_requisition(self): if not self.requisition_lines: @@ -140,6 +117,7 @@ class Requisition(models.Model): vendor_ids = self.env['requisition.line'].read_group([('requisition_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id']) counter_po_number = 0 + po_ids = [] for vendor in vendor_ids: param_header = { 'partner_id': vendor['partner_id'][0], @@ -152,25 +130,29 @@ class Requisition(models.Model): 'sale_order_id': self.sale_order_id.id, 'note_description': 'from Purchase Requisition' } - # new_po = self.env['purchase.order'].create([param_header]) - products_vendors = self.env['requisition.line'].search([ + param_requisition_line = [ ('requisition_id', '=', self.id), ('partner_id', '=', vendor['partner_id'][0]), ('qty_purchase', '>', 0) - ], order='brand_id') + ] + # new_po = self.env['purchase.order'].create([param_header]) + products_vendors = self.env['requisition.line'].search(, order='brand_id') count = brand_id = 0 for product in products_vendors: - if count == 200 or brand_id != product.brand_id.id: - count = 0 - counter_po_number += 1 - new_po = self.env['purchase.order'].create([param_header]) - new_po.name = new_po.name + "/R/"+str(counter_po_number) - self.env['requisition.purchase.match'].create([{ - 'requisition_id': self.id, - 'order_id': new_po.id - }]) - self.env.cr.commit() + if count > 200 or brand_id != product.brand_id.id: + continue + + count = 0 + counter_po_number += 1 + new_po = self.env['purchase.order'].create([param_header]) + new_po.name = new_po.name + "/R/"+str(counter_po_number) + self.env['requisition.purchase.match'].create([{ + 'requisition_id': self.id, + 'order_id': new_po.id + }]) + po_ids.append(new_po.id) + self.env.cr.commit() # else: # new_po = self.env['purchase.order'].create([param_header]) brand_id = product.brand_id.id @@ -184,7 +166,7 @@ class Requisition(models.Model): tax = [22] param_line = { - 'order_id': new_po.id, + 'sequence': count, 'product_id': product.product_id.id, 'product_qty': product.qty_purchase, @@ -195,11 +177,24 @@ class Requisition(models.Model): # 'suggest': suggest, } new_line = self.env['purchase.order.line'].create([param_line]) + if new_po: + new_line.write({ + 'order_id': new_po.id, + }) product.current_po_id = new_po.id product.current_po_line_id = new_line.id _logger.info('Create PO Line %s' % product.product_id.name) # self.notification = self.notification + ' %s' % new_po.name self.is_po = True + if po_ids: + return { + 'name': _('Purchase Order'), + 'view_mode': 'tree,form', + 'res_model': 'purchase.order', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', po_ids)], + } class RequisitionLine(models.Model): _name = 'requisition.line' -- cgit v1.2.3 From 0c21532c6aa129cbafa80b6b67caf5526688b7d8 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 31 Jan 2024 16:23:11 +0700 Subject: fix error --- indoteknik_custom/models/requisition.py | 170 ++++++++++++++++---------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index d6b33044..f3dd5093 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -108,93 +108,93 @@ class Requisition(models.Model): line.current_po_line_id = new_po_line.id return po_ids - def create_po_from_requisition(self): - if not self.requisition_lines: - raise UserError('Tidak ada Lines, belum bisa create PO') - if self.is_po: - raise UserError('Sudah pernah di create PO') - current_time = datetime.now() - vendor_ids = self.env['requisition.line'].read_group([('requisition_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id']) + # def create_po_from_requisition(self): + # if not self.requisition_lines: + # raise UserError('Tidak ada Lines, belum bisa create PO') + # if self.is_po: + # raise UserError('Sudah pernah di create PO') + # current_time = datetime.now() + # vendor_ids = self.env['requisition.line'].read_group([('requisition_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id']) - counter_po_number = 0 - po_ids = [] - for vendor in vendor_ids: - param_header = { - 'partner_id': vendor['partner_id'][0], - # 'partner_ref': self.sale_order_id.name, - 'currency_id': 12, - 'user_id': self.env.user.id, - 'company_id': 1, # indoteknik dotcom gemilang - 'picking_type_id': 28, # indoteknik bandengan receipts - 'date_order': current_time, - 'sale_order_id': self.sale_order_id.id, - 'note_description': 'from Purchase Requisition' - } - param_requisition_line = [ - ('requisition_id', '=', self.id), - ('partner_id', '=', vendor['partner_id'][0]), - ('qty_purchase', '>', 0) - ] - # new_po = self.env['purchase.order'].create([param_header]) - products_vendors = self.env['requisition.line'].search(, order='brand_id') - count = brand_id = 0 - - for product in products_vendors: - if count > 200 or brand_id != product.brand_id.id: - continue - - count = 0 - counter_po_number += 1 - new_po = self.env['purchase.order'].create([param_header]) - new_po.name = new_po.name + "/R/"+str(counter_po_number) - self.env['requisition.purchase.match'].create([{ - 'requisition_id': self.id, - 'order_id': new_po.id - }]) - po_ids.append(new_po.id) - self.env.cr.commit() - # else: - # 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' - - tax = [22] - - param_line = { + # counter_po_number = 0 + # po_ids = [] + # for vendor in vendor_ids: + # param_header = { + # 'partner_id': vendor['partner_id'][0], + # # 'partner_ref': self.sale_order_id.name, + # 'currency_id': 12, + # 'user_id': self.env.user.id, + # 'company_id': 1, # indoteknik dotcom gemilang + # 'picking_type_id': 28, # indoteknik bandengan receipts + # 'date_order': current_time, + # 'sale_order_id': self.sale_order_id.id, + # 'note_description': 'from Purchase Requisition' + # } + # param_requisition_line = [ + # ('requisition_id', '=', self.id), + # ('partner_id', '=', vendor['partner_id'][0]), + # ('qty_purchase', '>', 0) + # ] + # # new_po = self.env['purchase.order'].create([param_header]) + # products_vendors = self.env['requisition.line'].search(, order='brand_id') + # count = brand_id = 0 + + # for product in products_vendors: + # if count > 200 or brand_id != product.brand_id.id: + # continue + + # count = 0 + # counter_po_number += 1 + # new_po = self.env['purchase.order'].create([param_header]) + # new_po.name = new_po.name + "/R/"+str(counter_po_number) + # self.env['requisition.purchase.match'].create([{ + # 'requisition_id': self.id, + # 'order_id': new_po.id + # }]) + # po_ids.append(new_po.id) + # self.env.cr.commit() + # # else: + # # 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' + + # tax = [22] + + # param_line = { - 'sequence': count, - 'product_id': product.product_id.id, - 'product_qty': product.qty_purchase, - 'product_uom_qty': product.qty_purchase, - 'price_unit': product.price_unit, - 'taxes_id': tax, - # 'qty_available_store': qty_available, - # 'suggest': suggest, - } - new_line = self.env['purchase.order.line'].create([param_line]) - if new_po: - new_line.write({ - 'order_id': new_po.id, - }) - product.current_po_id = new_po.id - product.current_po_line_id = new_line.id - _logger.info('Create PO Line %s' % product.product_id.name) - # self.notification = self.notification + ' %s' % new_po.name - self.is_po = True - if po_ids: - return { - 'name': _('Purchase Order'), - 'view_mode': 'tree,form', - 'res_model': 'purchase.order', - 'target': 'current', - 'type': 'ir.actions.act_window', - 'domain': [('id', 'in', po_ids)], - } + # 'sequence': count, + # 'product_id': product.product_id.id, + # 'product_qty': product.qty_purchase, + # 'product_uom_qty': product.qty_purchase, + # 'price_unit': product.price_unit, + # 'taxes_id': tax, + # # 'qty_available_store': qty_available, + # # 'suggest': suggest, + # } + # new_line = self.env['purchase.order.line'].create([param_line]) + # if new_po: + # new_line.write({ + # 'order_id': new_po.id, + # }) + # product.current_po_id = new_po.id + # product.current_po_line_id = new_line.id + # _logger.info('Create PO Line %s' % product.product_id.name) + # # self.notification = self.notification + ' %s' % new_po.name + # self.is_po = True + # if po_ids: + # return { + # 'name': _('Purchase Order'), + # 'view_mode': 'tree,form', + # 'res_model': 'purchase.order', + # 'target': 'current', + # 'type': 'ir.actions.act_window', + # 'domain': [('id', 'in', po_ids)], + # } class RequisitionLine(models.Model): _name = 'requisition.line' -- cgit v1.2.3 From fe804076d721bd9c820714119796df5868ddac17 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Wed, 31 Jan 2024 16:27:59 +0700 Subject: fix error id --- indoteknik_custom/models/requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index f3dd5093..a61a5008 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -97,7 +97,7 @@ class Requisition(models.Model): for line in lines: product = line.product_id param_line = { - 'product_id': product.product_id.id, + 'product_id': product.id, 'product_qty': product.qty_purchase, 'product_uom_qty': product.qty_purchase, 'price_unit': product.price_unit, -- cgit v1.2.3 From 61106232cf4563d1d59dad97833f2c3ed2f36298 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 1 Feb 2024 08:42:44 +0700 Subject: fix error requisition --- indoteknik_custom/models/requisition.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index a61a5008..ec369777 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -98,9 +98,9 @@ class Requisition(models.Model): product = line.product_id param_line = { 'product_id': product.id, - 'product_qty': product.qty_purchase, - 'product_uom_qty': product.qty_purchase, - 'price_unit': product.price_unit, + 'product_qty': line.qty_purchase, + 'product_uom_qty': line.qty_purchase, + 'price_unit': line.price_unit, 'taxes_id': tax, } new_po_line = self.env['purchase.order.line'].create([param_line]) -- cgit v1.2.3 From e698f0fb7f0ca1af02fd242e311ef30a6923c0b0 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 1 Feb 2024 08:54:56 +0700 Subject: trying to fix error requisition --- indoteknik_custom/models/requisition.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index ec369777..6fe65f5e 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -100,6 +100,7 @@ class Requisition(models.Model): 'product_id': product.id, 'product_qty': line.qty_purchase, 'product_uom_qty': line.qty_purchase, + 'product_uom_qty': product.uom_po_id.id, 'price_unit': line.price_unit, 'taxes_id': tax, } -- cgit v1.2.3 From 396094a96ec54e78887111739d10ae6ab661d23e Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 1 Feb 2024 08:55:57 +0700 Subject: change name data on object --- indoteknik_custom/models/requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 6fe65f5e..d2cb7ecf 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -100,7 +100,7 @@ class Requisition(models.Model): 'product_id': product.id, 'product_qty': line.qty_purchase, 'product_uom_qty': line.qty_purchase, - 'product_uom_qty': product.uom_po_id.id, + 'product_uom': product.uom_po_id.id, 'price_unit': line.price_unit, 'taxes_id': tax, } -- cgit v1.2.3 From e948221236257983529358c39f263ccbdf73b1c6 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 1 Feb 2024 09:01:54 +0700 Subject: trying to fix error requisition --- indoteknik_custom/models/requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index d2cb7ecf..0607dc84 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -100,7 +100,7 @@ class Requisition(models.Model): 'product_id': product.id, 'product_qty': line.qty_purchase, 'product_uom_qty': line.qty_purchase, - 'product_uom': product.uom_po_id.id, + 'name': product.name, 'price_unit': line.price_unit, 'taxes_id': tax, } -- cgit v1.2.3 From f53bdfb91b2f91765aa9d61842f41b571fe12cee Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Thu, 1 Feb 2024 09:03:18 +0700 Subject: compute commision percent --- indoteknik_custom/models/commision.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py index a9ad624c..955d1634 100644 --- a/indoteknik_custom/models/commision.py +++ b/indoteknik_custom/models/commision.py @@ -159,12 +159,14 @@ class CustomerCommision(models.Model): @api.constrains('commision_percent') def _onchange_commision_percent(self): print('masuk onchange commision percent') - self.commision_amt = self.commision_percent * self.total_dpp // 100 + if self.commision_amt == 0: + self.commision_amt = self.commision_percent * self.total_dpp // 100 - # @api.constrains('commision_amt') - # def _onchange_commision_amt(self): - # print('masuk onchange commision amt') - # self.commision_percent = (self.commision_amt / self.grand_total * 100) + @api.constrains('commision_amt') + def _onchange_commision_amt(self): + print('masuk onchange commision amt') + if self.commision_percent == 0: + self.commision_percent = (self.commision_amt / self.total_dpp * 100) def _compute_total_dpp(self): for data in self: @@ -176,6 +178,11 @@ class CustomerCommision(models.Model): @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('customer.commision') or '0' + # if vals['commision_amt'] > 0: + # commision_amt = vals['commision_amt'] + # total_dpp = vals['total_dpp'] + # commision_percent = commision_amt / total_dpp * 100 + # vals['commision_percent'] = commision_percent result = super(CustomerCommision, self).create(vals) return result -- cgit v1.2.3 From 7e59db23fb69402cd622c7a932e8e980ab216151 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 1 Feb 2024 09:04:04 +0700 Subject: trying to fix error requisition --- indoteknik_custom/models/requisition.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 0607dc84..5072b394 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -97,6 +97,7 @@ class Requisition(models.Model): for line in lines: product = line.product_id param_line = { + 'order_id' : new_po.id, 'product_id': product.id, 'product_qty': line.qty_purchase, 'product_uom_qty': line.qty_purchase, -- cgit v1.2.3 From fe086f5052ab5ba66c458ce25d50f7804c705211 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 1 Feb 2024 09:16:03 +0700 Subject: fix return --- indoteknik_custom/models/requisition.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 5072b394..2b148c96 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -44,7 +44,7 @@ class Requisition(models.Model): po_ids = [] for vendor in vendor_ids: result_po = self.create_po_by_vendor(vendor['partner_id'][0]) - po_ids.append(result_po) + po_ids += result_po return { 'name': _('Purchase Order'), 'view_mode': 'tree,form', -- cgit v1.2.3 From 6f0b80656e318914d56d085f9b9e08ccd9838450 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 1 Feb 2024 11:41:28 +0700 Subject: fix bug qty purchase and change request fiture delete line --- indoteknik_custom/models/purchase_order.py | 4 ++-- indoteknik_custom/models/purchase_order_line.py | 28 +++++++++++++++++++++++++ indoteknik_custom/views/purchase_order.xml | 4 ++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index ebadff06..67299d2c 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -54,9 +54,9 @@ class PurchaseOrder(models.Model): revisi_po = fields.Boolean(string='Revisi', tracking=3) def delete_line(self): - lines_to_delete = self.order_line.filtered(lambda line: line.delete_line) + lines_to_delete = self.order_line.filtered(lambda line: line.suggest == 'masih cukup') if not lines_to_delete: - raise UserError('Tidak ada item yang dipilih') + raise UserError('Tidak ada item yang masih cukup') lines_to_delete.unlink() def open_form_multi_confirm_po(self): diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 465944d5..f1881942 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -36,6 +36,34 @@ class PurchaseOrderLine(models.Model): note = fields.Char(string='Note') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') delete_line = fields.Boolean(string='Delete', default=False, help='centang ini jika anda ingin menghapus line ini') + is_edit_product_qty = fields.Boolean(string='Is Edit Product Qty', compute='_compute_is_edit_product_qty') + + def _compute_is_edit_product_qty(self): + for line in self: + + if line.order_id.state in ['draft']: + is_valid = True + else: + is_valid = False + + line.is_edit_product_qty = is_valid + + # @api.constrains('product_qty') + # def change_qty_po_and_qty_demand(self): + # for line in self: + # if line.order_id.state in ['draft', 'cancel'] and len(line.order_id.picking_ids) == 0: + # continue + + # for stock_picking in line.order_id.picking_ids: + # picking = self.env['stock.move'].search([ + # ('picking_id.purchase_id', '=', line.order_id.id), + # ('product_id', '=', line.product_id.id) + # ]) + + # if picking: + # picking.write({ + # 'product_uom_qty': line.product_qty + # }) def _compute_qty_reserved(self): for line in self: diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 48443057..52e98787 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -52,12 +52,12 @@ - {'no_create': True} + @@ -102,7 +102,7 @@ - {'readonly': [], 'required': True} + {'readonly': [('is_edit_product_qty', '=', False)], 'required': True} -- cgit v1.2.3 From 8bc43445f1d0b70d54d0a45830e04d0fcc406fbe Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 1 Feb 2024 15:24:17 +0700 Subject: Fix image watermark API --- indoteknik_api/controllers/controller.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 0592afe1..a362e6a6 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -230,16 +230,6 @@ class Controller(http.Controller): new_img = img - if version == '2': - logo__footer_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', 'logo-indoteknik-footer.png') - logo__footer_img = Image.open(logo__footer_path).convert('RGBA') - logo__footer_img.thumbnail((img_width, img_height // 1)) - logo_footer_w, logo_footer_h = logo__footer_img.size - new_img.paste(logo__footer_img, (0, img_height - logo_footer_h), logo__footer_img) - - logo_img_w = img_width // 1.8 - logo_img_h = img_height // 1.8 - if ratio == 'square': new_img = Image.new('RGBA', (longest_wh, longest_wh), (255, 255, 255, 255)) @@ -247,6 +237,16 @@ class Controller(http.Controller): paste_y = (longest_wh - img_height) // 2 new_img.paste(img, (paste_x, paste_y), img) + + if version == '2': + logo__footer_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', 'logo-indoteknik-footer.png') + logo_footer_img = Image.open(logo__footer_path).convert('RGBA') + logo_footer_img.thumbnail((img_width, img_height // 1)) + logo_footer_w, logo_footer_h = logo_footer_img.size + new_img.paste(logo_footer_img, (0, img_height - logo_footer_h), logo_footer_img) + + logo_img_w = img_width // 1.8 + logo_img_h = img_height // 1.8 logo_img.thumbnail((logo_img_w, logo_img_h)) -- cgit v1.2.3 From d6c7fad834f954f892cea0eb9e082db822bc8f2b Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 2 Feb 2024 08:58:09 +0700 Subject: fix error purchase pricelist --- indoteknik_custom/models/purchase_pricelist.py | 27 +++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 805ebc89..67b22e4c 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -39,8 +39,7 @@ class PurchasePricelist(models.Model): if price_unit == 0: self.include_price = 0 return - # taxes = self.taxes_system_id or self.taxes_product_id - # price_unit = self.system_price or self.product_price + tax_include = taxes.price_include if taxes: if tax_include: @@ -53,18 +52,20 @@ class PurchasePricelist(models.Model): self.include_price = price_unit def _get_valid_price(self): - p_price = 0 - taxes = False + purchase_price = self + price = 0 + taxes = None + human_last_update = purchase_price.human_last_update or datetime.min + system_last_update = purchase_price.system_last_update or datetime.min - if self.system_price > 0: - if self.product_price > 0 and self.human_last_update > self.system_last_update: - p_price, taxes = self.product_price, self.taxes_product_id - else: - p_price, taxes = self.system_price, self.taxes_system_id - elif self.product_price > 0: - p_price, taxes = self.product_price, self.taxes_product_id - - return p_price, taxes + if system_last_update > human_last_update: + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id + else: + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id + + return price, taxes @api.constrains('vendor_id', 'product_id') def _check_duplicate_purchase_pricelist(self): -- cgit v1.2.3 From 8978868864925683d02342112020e7fc047a4acf Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 2 Feb 2024 13:32:55 +0700 Subject: logbook sj and mark as cancel po --- indoteknik_custom/__manifest__.py | 11 +++ indoteknik_custom/models/__init__.py | 11 +++ indoteknik_custom/models/logbook_sj.py | 117 +++++++++++++++++++++++++ indoteknik_custom/models/po_multi_cancel.py | 22 +++++ indoteknik_custom/models/purchase_order.py | 19 ++++ indoteknik_custom/models/report_logbook_sj.py | 34 +++++++ indoteknik_custom/security/ir.model.access.csv | 17 +++- indoteknik_custom/views/logbook_sj.xml | 52 +++++++++++ indoteknik_custom/views/po_multi_cancel.xml | 31 +++++++ indoteknik_custom/views/purchase_order.xml | 9 ++ indoteknik_custom/views/report_logbook_sj.xml | 90 +++++++++++++++++++ 11 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 indoteknik_custom/models/logbook_sj.py create mode 100644 indoteknik_custom/models/po_multi_cancel.py create mode 100644 indoteknik_custom/models/report_logbook_sj.py create mode 100644 indoteknik_custom/views/logbook_sj.xml create mode 100644 indoteknik_custom/views/po_multi_cancel.xml create mode 100644 indoteknik_custom/views/report_logbook_sj.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index c7e65b37..689103d8 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -107,6 +107,17 @@ 'views/purchase_order_multi_update.xml', 'views/purchase_order_multi_confirm.xml', 'views/invoice_reklas_penjualan.xml', +<<<<<<< Updated upstream +<<<<<<< Updated upstream + 'views/po_multi_cancel.xml', +======= + 'views/logbook_sj.xml', + 'views/report_logbook_sj.xml', +>>>>>>> Stashed changes +======= + 'views/logbook_sj.xml', + 'views/report_logbook_sj.xml', +>>>>>>> Stashed changes 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 76387ff8..4b29e71d 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -98,3 +98,14 @@ from . import purchase_order_multi_update from . import invoice_reklas_penjualan from . import purchase_order_multi_confirm from . import stock_quant +<<<<<<< Updated upstream +<<<<<<< Updated upstream +from . import po_multi_cancel +======= +from . import logbook_sj +from . import report_logbook_sj +>>>>>>> Stashed changes +======= +from . import logbook_sj +from . import report_logbook_sj +>>>>>>> Stashed changes diff --git a/indoteknik_custom/models/logbook_sj.py b/indoteknik_custom/models/logbook_sj.py new file mode 100644 index 00000000..567f1ae3 --- /dev/null +++ b/indoteknik_custom/models/logbook_sj.py @@ -0,0 +1,117 @@ +from odoo import models, fields, api, _ +from odoo.exceptions import UserError +from pytz import timezone +from datetime import datetime + +class LogbookSJ(models.TransientModel): + _name = 'logbook.sj' + + name = fields.Char(string='Name', default='Logbook SJ') + logbook_sj_line = fields.One2many( + comodel_name='logbook.sj.line', + inverse_name='logbook_sj_id', + string='Logbook SJ Line' + ) + + def create_logbook_sj(self): + logbook_line = self.logbook_sj_line + + current_time = datetime.utcnow() + report_logbook_ids = [] + for line in logbook_line: + nomor_sj = line.name + picking = self.env['stock.picking'].search([ + ('picking_code', '=', nomor_sj), + ]) + parameters_header = { + 'name': nomor_sj, + 'date': current_time, + 'name_picking': picking.name, + 'partner_id': picking.partner_id.id, + } + + report_logbook = self.env['report.logbook.sj'].create([parameters_header]) + + + for stock in picking.move_line_ids_without_package: + data = { + 'product_id': stock.product_id.id, + 'location_id': stock.location_id.id, + 'product_uom_qty': stock.product_uom_qty, + 'qty_done': stock.qty_done, + 'product_uom_id': stock.product_uom_id.id, + 'report_logbook_sj_id': report_logbook.id + } + self.env['report.logbook.sj.line'].create([data]) + + report_logbook_ids.append(report_logbook.id) + line.unlink() + + self.unlink() + return { + 'name': _('Report Logbook SJ'), + 'view_mode': 'tree,form', + 'res_model': 'report.logbook.sj', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', report_logbook_ids)], + } + +class LogbookSJLine(models.TransientModel): + _name = 'logbook.sj.line' + + name = fields.Char(string='SJ Number') + driver_id = fields.Many2one(comodel_name='res.users', string='Driver') + departure_date = fields.Char(string='Departure Date') + arrival_date = fields.Char(string='Arrival Date') + carrier_id = fields.Many2one('delivery.carrier', string='Shipping Method') + tracking_no = fields.Char(string='Tracking No') + logbook_sj_id = fields.Many2one('logbook.sj', string='Logbook SJ') + partner_id = fields.Many2one('res.partner', string='Customer') + + @api.onchange('name') + def onchange_name(self): + current_time = datetime.now(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') + + if self.name: + if len(self.name) == 13: + self.name = self.name[:-1] + picking = self.env['stock.picking'].search([('picking_code', '=', self.name)], limit=1) + if picking: + if picking.driver_id: + self.driver_id = picking.driver_id + else: + self.driver_id = self.env.uid + + sale_order = False + if picking.origin: + sale_order = self.env['sale.order'].search([('name', '=', picking.origin)], limit=1) + + if sale_order.carrier_id: + self.carrier_id = sale_order.carrier_id + + self.tracking_no = picking.delivery_tracking_no + + self.partner_id = picking.partner_id + + delivery_type = self.get_delivery_type(picking.driver_departure_date, picking.driver_arrival_date) + if delivery_type != 'departure': + self.departure_date = picking.driver_departure_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') + + if delivery_type == 'departure': + self.departure_date = current_time + elif delivery_type == 'arrival': + self.arrival_date = current_time + else: + self.arrival_date = picking.driver_arrival_date.astimezone(timezone('Asia/Jakarta')).strftime('%Y-%m-%d %H:%M:%S') + else: + raise UserError('Nomor DO tidak ditemukan') + + def get_delivery_type(self, driver_departure_date, driver_arrival_date): + delivery_type = 'departure' + if driver_departure_date: + delivery_type = 'arrival' + if driver_arrival_date: + delivery_type = False + + return delivery_type diff --git a/indoteknik_custom/models/po_multi_cancel.py b/indoteknik_custom/models/po_multi_cancel.py new file mode 100644 index 00000000..52c156b5 --- /dev/null +++ b/indoteknik_custom/models/po_multi_cancel.py @@ -0,0 +1,22 @@ +from odoo import models, fields +import logging + +_logger = logging.getLogger(__name__) + + +class PoMultiCancel(models.TransientModel): + _name = 'po.multi.cancel' + + def save_multi_cancel_po(self): + purchase_ids = self._context['purchase_ids'] + purchase = self.env['purchase.order'].browse(purchase_ids) + purchase.button_cancel() + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Notification', + 'message': 'Status berhasil diubah', + 'next': {'type': 'ir.actions.act_window_close'}, + } + } \ No newline at end of file diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 67299d2c..dc654196 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -53,6 +53,25 @@ class PurchaseOrder(models.Model): status_paid_cbd = fields.Boolean(string='Paid Status', tracking=3, help='Field ini diisi secara manual oleh Finance AP dan hanya untuk status PO CBD') revisi_po = fields.Boolean(string='Revisi', tracking=3) + @api.model + def action_multi_cancel(self): + for purchase in self: + purchase.update({ + 'state': 'cancel', + }) + + if purchase.state == 'cancel': + purchase.update({ + 'approval_status': False, + }) + + def open_form_multi_cancel(self): + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_po_multi_cancel') + action['context'] = { + 'purchase_ids': [x.id for x in self] + } + return action + def delete_line(self): lines_to_delete = self.order_line.filtered(lambda line: line.suggest == 'masih cukup') if not lines_to_delete: diff --git a/indoteknik_custom/models/report_logbook_sj.py b/indoteknik_custom/models/report_logbook_sj.py new file mode 100644 index 00000000..d2008608 --- /dev/null +++ b/indoteknik_custom/models/report_logbook_sj.py @@ -0,0 +1,34 @@ +from odoo import models, fields, api +from odoo.exceptions import UserError +from pytz import timezone +from datetime import datetime + +class ReportLogbookSJ(models.Model): + _name = 'report.logbook.sj' + + name = fields.Char(string='Nomor SJ', default='Logbook SJ') + date = fields.Datetime(string='Date') + name_picking = fields.Char(string='Picking Name') + partner_id = fields.Many2one('res.partner', string='Customer') + approve_by_finance = fields.Boolean(string='Approve By Finance') + report_logbook_sj_line = fields.One2many( + comodel_name='report.logbook.sj.line', + inverse_name='report_logbook_sj_id', + string='Logbook SJ Line' + ) + + def approve(self): + if self.env.user.is_accounting: + self.approve_by_finance = True + else: + raise UserError('Hanya Accounting yang bisa Approve') + +class ReportLogbookSJLine(models.Model): + _name = 'report.logbook.sj.line' + + product_id = fields.Many2one(comodel_name='product.product', string='Product') + location_id = fields.Many2one(comodel_name='stock.location', string='From') + product_uom_qty = fields.Float(string='Reserved') + qty_done = fields.Float(string='Done') + product_uom_id = fields.Many2one('uom.uom', string='Unit of Measure') + report_logbook_sj_id = fields.Many2one('report.logbook.sj', string='Logbook SJ') \ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 8d014b69..c2bfaa10 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -88,4 +88,19 @@ access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advan access_purchase_order_multi_update,access.purchase.order.multi_update,model_purchase_order_multi_update,,1,1,1,1 access_invoice_reklas_penjualan,access.invoice.reklas.penjualan,model_invoice_reklas_penjualan,,1,1,1,1 access_invoice_reklas_penjualan_line,access.invoice.reklas.penjualan.line,model_invoice_reklas_penjualan_line,,1,1,1,1 -access_purchase_order_multi_confirm,access.purchase.order.multi_confirm,model_purchase_order_multi_confirm,,1,1,1,1 \ No newline at end of file +access_purchase_order_multi_confirm,access.purchase.order.multi_confirm,model_purchase_order_multi_confirm,,1,1,1,1 +<<<<<<< Updated upstream +<<<<<<< Updated upstream +access_po_multi_cancel,access.po.multi.cancel,model_po_multi_cancel,,1,1,1,1 +======= +access_logbook_sj,access.logbook.sj,model_logbook_sj,,1,1,1,1 +access_logbook_sj_line,access.logbook.sj.line,model_logbook_sj_line,,1,1,1,1 +access_report_logbook_sj,access.report.logbook.sj,model_report_logbook_sj,,1,1,1,1 +access_report_logbook_sj_line,access.report.logbook.sj.line,model_report_logbook_sj_line,,1,1,1,1 +>>>>>>> Stashed changes +======= +access_logbook_sj,access.logbook.sj,model_logbook_sj,,1,1,1,1 +access_logbook_sj_line,access.logbook.sj.line,model_logbook_sj_line,,1,1,1,1 +access_report_logbook_sj,access.report.logbook.sj,model_report_logbook_sj,,1,1,1,1 +access_report_logbook_sj_line,access.report.logbook.sj.line,model_report_logbook_sj_line,,1,1,1,1 +>>>>>>> Stashed changes diff --git a/indoteknik_custom/views/logbook_sj.xml b/indoteknik_custom/views/logbook_sj.xml new file mode 100644 index 00000000..9eb9aa12 --- /dev/null +++ b/indoteknik_custom/views/logbook_sj.xml @@ -0,0 +1,52 @@ + + + + Logbook SJ + logbook.sj + +
+ + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + Logbook SJ + logbook.sj + ir.actions.act_window + form + + new + + + +
\ No newline at end of file diff --git a/indoteknik_custom/views/po_multi_cancel.xml b/indoteknik_custom/views/po_multi_cancel.xml new file mode 100644 index 00000000..c17fc5a7 --- /dev/null +++ b/indoteknik_custom/views/po_multi_cancel.xml @@ -0,0 +1,31 @@ + + + + + PO Multi Cancel + po.multi.cancel + +
+ + + Apakah Anda Yakin Ingin Mengubah Status Menjadi Cancel? + + +
+
+
+
+
+ + + PO Multi Cancel + po.multi.cancel + ir.actions.act_window + form + + new + +
+
\ No newline at end of file diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 52e98787..a6f28ffa 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -213,4 +213,13 @@ action = records.open_form_multi_confirm_po() + + + Cancel PO + + + code + action = records.open_form_multi_cancel() + + \ No newline at end of file diff --git a/indoteknik_custom/views/report_logbook_sj.xml b/indoteknik_custom/views/report_logbook_sj.xml new file mode 100644 index 00000000..52e00d17 --- /dev/null +++ b/indoteknik_custom/views/report_logbook_sj.xml @@ -0,0 +1,90 @@ + + + + report.logbook.sj.tree + report.logbook.sj + + + + + + + + + + + + + report.logbook.sj.line.tree + report.logbook.sj.line + + + + + + + + + + + + + report.logbook.sj.form + report.logbook.sj + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + Report Logbook SJ + ir.actions.act_window + report.logbook.sj + tree,form + + + + \ No newline at end of file -- cgit v1.2.3 From e8edbf3d6b2c2edd67a890a29fb6262794e730d9 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 2 Feb 2024 13:35:08 +0700 Subject: fix conflict --- indoteknik_custom/__manifest__.py | 8 -------- indoteknik_custom/models/__init__.py | 10 +--------- indoteknik_custom/security/ir.model.access.csv | 10 ---------- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 689103d8..b8a5f6f8 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -107,17 +107,9 @@ 'views/purchase_order_multi_update.xml', 'views/purchase_order_multi_confirm.xml', 'views/invoice_reklas_penjualan.xml', -<<<<<<< Updated upstream -<<<<<<< Updated upstream 'views/po_multi_cancel.xml', -======= 'views/logbook_sj.xml', 'views/report_logbook_sj.xml', ->>>>>>> Stashed changes -======= - 'views/logbook_sj.xml', - 'views/report_logbook_sj.xml', ->>>>>>> Stashed changes 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 4b29e71d..9678329a 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -98,14 +98,6 @@ from . import purchase_order_multi_update from . import invoice_reklas_penjualan from . import purchase_order_multi_confirm from . import stock_quant -<<<<<<< Updated upstream -<<<<<<< Updated upstream from . import po_multi_cancel -======= from . import logbook_sj -from . import report_logbook_sj ->>>>>>> Stashed changes -======= -from . import logbook_sj -from . import report_logbook_sj ->>>>>>> Stashed changes +from . import report_logbook_sj \ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index c2bfaa10..31503dbe 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -89,18 +89,8 @@ access_purchase_order_multi_update,access.purchase.order.multi_update,model_purc access_invoice_reklas_penjualan,access.invoice.reklas.penjualan,model_invoice_reklas_penjualan,,1,1,1,1 access_invoice_reklas_penjualan_line,access.invoice.reklas.penjualan.line,model_invoice_reklas_penjualan_line,,1,1,1,1 access_purchase_order_multi_confirm,access.purchase.order.multi_confirm,model_purchase_order_multi_confirm,,1,1,1,1 -<<<<<<< Updated upstream -<<<<<<< Updated upstream access_po_multi_cancel,access.po.multi.cancel,model_po_multi_cancel,,1,1,1,1 -======= access_logbook_sj,access.logbook.sj,model_logbook_sj,,1,1,1,1 access_logbook_sj_line,access.logbook.sj.line,model_logbook_sj_line,,1,1,1,1 access_report_logbook_sj,access.report.logbook.sj,model_report_logbook_sj,,1,1,1,1 access_report_logbook_sj_line,access.report.logbook.sj.line,model_report_logbook_sj_line,,1,1,1,1 ->>>>>>> Stashed changes -======= -access_logbook_sj,access.logbook.sj,model_logbook_sj,,1,1,1,1 -access_logbook_sj_line,access.logbook.sj.line,model_logbook_sj_line,,1,1,1,1 -access_report_logbook_sj,access.report.logbook.sj,model_report_logbook_sj,,1,1,1,1 -access_report_logbook_sj_line,access.report.logbook.sj.line,model_report_logbook_sj_line,,1,1,1,1 ->>>>>>> Stashed changes -- cgit v1.2.3 From f5edc62d22c9a3973261ad289a11e189f0866f52 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 2 Feb 2024 13:36:48 +0700 Subject: fix conflict --- indoteknik_custom/models/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 9678329a..49e3567c 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -100,4 +100,4 @@ from . import purchase_order_multi_confirm from . import stock_quant from . import po_multi_cancel from . import logbook_sj -from . import report_logbook_sj \ No newline at end of file +from . import report_logbook_sj -- cgit v1.2.3 From 0a71a9cb02bf3ceb317a41f4550f9d7fe6370f56 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Fri, 2 Feb 2024 14:08:37 +0700 Subject: Refactor lead auto assign to salesperson --- indoteknik_custom/models/crm_lead.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/indoteknik_custom/models/crm_lead.py b/indoteknik_custom/models/crm_lead.py index d181c35b..e8721142 100755 --- a/indoteknik_custom/models/crm_lead.py +++ b/indoteknik_custom/models/crm_lead.py @@ -80,18 +80,11 @@ class CrmLead(models.Model): input_tags.append(1510) #no tag lead.tag_ids = input_tags - if not lead.user_id or lead.user_id.id in [25]: - partner = lead.partner_id.parent_id or lead.partner_id - if partner.user_id and partner.user_id.id not in [25]: - salesperson_id = partner.user_id.id - else: - salesperson_id = 2 - else: - partner = lead.partner_id.parent_id or lead.partner_id - if partner.user_id and partner.user_id.id not in [25]: - salesperson_id = partner.user_id.id - else: - salesperson_id = 2 + salesperson_id = 2 + + partner = lead.partner_id.parent_id or lead.partner_id + if partner.user_id and partner.user_id.id not in [25]: + salesperson_id = partner.user_id.id lead.user_id = salesperson_id -- cgit v1.2.3 From 0df91a475b7d5cedff2c0ffcaa079c0ad69fb402 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 5 Feb 2024 11:44:04 +0700 Subject: Update solr image on product variant --- indoteknik_custom/models/solr/product_product.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index 6a0073bd..ac41dbff 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -48,6 +48,13 @@ class ProductProduct(models.Model): category_name = category.name document = solr_model.get_doc('variants', variant.id) + + image = '' + if variant.image_256: + image = ir_attachment.api_image('product.product', 'image_256', variant.id) + else: + image = ir_attachment.api_image('product.template', 'image_256', variant.product_tmpl_id.id) + document.update({ 'id': variant.id, 'display_name_s': variant.display_name, @@ -56,8 +63,7 @@ class ProductProduct(models.Model): 'product_rating_f': variant.product_tmpl_id.virtual_rating, 'product_id_i': variant.id, 'template_id_i': variant.product_tmpl_id.id, - "image_s": ir_attachment.api_image('product.product', 'image_256', variant.id), - 'parent_image_s': ir_attachment.api_image('product.template', 'image_256', variant.product_tmpl_id.id), + "image_s": image, 'stock_total_f': variant.qty_stock_vendor, 'weight_f': variant.product_tmpl_id.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, -- cgit v1.2.3 From 1e995042f86bed5bf7b982d63bbad07c9db1410a Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 5 Feb 2024 14:40:47 +0700 Subject: Add helper ids on write sale order --- indoteknik_custom/models/sale_order.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index f00f5b1d..e5d7f687 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -360,9 +360,14 @@ class SaleOrder(models.Model): minimum_amount = 20000000 for order in self: order.have_visit_service = self.amount_total > minimum_amount + + def _get_helper_ids(self): + helper_ids_str = self.env['ir.config_parameter'].get_param('sale.order.user_helper_ids') + return helper_ids_str.split(', ') def write(self, values): - if self.env.user.id in [991, 20, 1180]: + helper_ids = self._get_helper_ids() + if str(self.env.user.id) in helper_ids: values['helper_by_id'] = self.env.user.id return super(SaleOrder, self).write(values) -- cgit v1.2.3 From 09422361b0158228309c2defb5b4149a75e9a27f Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 5 Feb 2024 15:09:40 +0700 Subject: Fix error access config parameter --- indoteknik_custom/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index e5d7f687..5173ccb7 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -362,7 +362,7 @@ class SaleOrder(models.Model): order.have_visit_service = self.amount_total > minimum_amount def _get_helper_ids(self): - helper_ids_str = self.env['ir.config_parameter'].get_param('sale.order.user_helper_ids') + helper_ids_str = self.env['ir.config_parameter'].sudo().get_param('sale.order.user_helper_ids') return helper_ids_str.split(', ') def write(self, values): -- cgit v1.2.3 From 6c0849185975b40039877f80c465a6beb6dead7d Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 6 Feb 2024 13:13:09 +0700 Subject: Update image watermark --- indoteknik_api/controllers/controller.py | 17 +++++------------ .../static/src/images/logo-indoteknik-footer.png | Bin 17722 -> 15294 bytes 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index a362e6a6..9ee56062 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -210,12 +210,7 @@ class Controller(http.Controller): def add_watermark_to_image(self, image, ratio, version = '1'): if not image: return '' - LOGO_FILENAME = { - '1': 'logo-indoteknik-gray.png', - '2': 'logo-indoteknik.png' - } - - logo_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', LOGO_FILENAME.get(version)) + logo_path = get_module_resource('indoteknik_api', 'static', 'src', 'images', 'logo-indoteknik-gray.png') logo_img = Image.open(logo_path).convert('RGBA') img_data = io.BytesIO(base64.b64decode(image)) @@ -243,15 +238,13 @@ class Controller(http.Controller): logo_footer_img = Image.open(logo__footer_path).convert('RGBA') logo_footer_img.thumbnail((img_width, img_height // 1)) logo_footer_w, logo_footer_h = logo_footer_img.size - new_img.paste(logo_footer_img, (0, img_height - logo_footer_h), logo_footer_img) - - logo_img_w = img_width // 1.8 - logo_img_h = img_height // 1.8 + new_img.paste(logo_footer_img, (0, img_height - logo_footer_h - 20), logo_footer_img) logo_img.thumbnail((logo_img_w, logo_img_h)) - # Add watermark - new_img.paste(logo_img, (12, 10), logo_img) + if version == '1': + # Add watermark + new_img.paste(logo_img, (12, 10), logo_img) buffered = io.BytesIO() new_img.save(buffered, format="PNG") diff --git a/indoteknik_api/static/src/images/logo-indoteknik-footer.png b/indoteknik_api/static/src/images/logo-indoteknik-footer.png index 4ebda906..fcd1ba70 100644 Binary files a/indoteknik_api/static/src/images/logo-indoteknik-footer.png and b/indoteknik_api/static/src/images/logo-indoteknik-footer.png differ -- cgit v1.2.3 From 4de40c41c5f1c7d1221cd177667e6935ea993b71 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 6 Feb 2024 13:36:16 +0700 Subject: Update variant not apply watermark --- indoteknik_api/controllers/controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index 9ee56062..50e86b68 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -190,7 +190,7 @@ class Controller(http.Controller): model = request.env[model].sudo().search([('id', '=', id)], limit=1) image = model[field] if field in model else '' - if model_name in ['product.template', 'product.product']: + if model_name in ['product.template']: version = '1' if field in ['image_256', 'image_512', 'image_1024', 'image_1920'] else '2' ratio = kw.get('ratio', '') image = model['image_256'] or '' -- cgit v1.2.3 From 1f25d11038dc36122a485694d5fc3374d98090d1 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 6 Feb 2024 15:32:08 +0700 Subject: Fix sale order calculate SO Status --- indoteknik_custom/models/sale_order.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 5173ccb7..24c642d9 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -262,17 +262,18 @@ class SaleOrder(models.Model): ('state', 'in', so_state), ('so_status', '!=', 'terproses'), ]) + for sale in sales: - picking_states = {'draft', 'assigned', 'confirmed', 'waiting'} + picking_states = ['draft', 'assigned', 'confirmed', 'waiting'] have_outstanding_pick = any(x.state in picking_states for x in sale.picking_ids) sum_qty_so = sum(so_line.product_uom_qty for so_line in sale.order_line) sum_qty_ship = sum(so_line.qty_delivered for so_line in sale.order_line) - if not have_outstanding_pick: - sale.so_status = 'terproses' - elif sum_qty_so > sum_qty_ship > 0: + if sum_qty_so > sum_qty_ship > 0: sale.so_status = 'sebagian' + elif not have_outstanding_pick: + sale.so_status = 'terproses' else: sale.so_status = 'menunggu' -- cgit v1.2.3 From f38eba228ef0e95ce3a0d1079f4d81153fc1b2ab Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 6 Feb 2024 16:16:13 +0700 Subject: fix error taxes --- indoteknik_custom/models/automatic_purchase.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index bf6901d3..ff566aa9 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -24,6 +24,7 @@ class AutomaticPurchase(models.Model): raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: raise UserError('Sudah pernah di create PO') + current_time = datetime.now() vendor_ids = self.env['automatic.purchase.line'].read_group([('automatic_purchase_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id']) @@ -47,6 +48,8 @@ class AutomaticPurchase(models.Model): ], order='brand_id') count = brand_id = 0 for product in products_vendors: + if not product.taxes_id: + raise UserError('Tidak ada Taxes') if count == 200 or brand_id != product.brand_id.id: count = 0 counter_po_number += 1 @@ -74,6 +77,7 @@ class AutomaticPurchase(models.Model): 'qty_available_store': qty_available, 'suggest': suggest, 'product_uom_qty': product.qty_purchase, + 'taxes_id': [product.taxes_id.id], 'price_unit': product.last_price, } new_line = self.env['purchase.order.line'].create([param_line]) @@ -145,12 +149,12 @@ class AutomaticPurchase(models.Model): human_last_update = purchase_price.human_last_update or datetime.min system_last_update = purchase_price.system_last_update or datetime.min + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id + if system_last_update > human_last_update: price = purchase_price.system_price taxes = purchase_price.taxes_system_id.id - else: - price = purchase_price.product_price - taxes = purchase_price.taxes_product_id.id return price, taxes -- cgit v1.2.3