diff options
21 files changed, 179 insertions, 156 deletions
diff --git a/indoteknik_api/controllers/api_v1/category.py b/indoteknik_api/controllers/api_v1/category.py index 09b8ff8c..7d66ad01 100644 --- a/indoteknik_api/controllers/api_v1/category.py +++ b/indoteknik_api/controllers/api_v1/category.py @@ -123,34 +123,47 @@ class Category(controller.Controller): return self.response(response_data) - @http.route(prefix + 'category/tree', auth='public', methods=['GET', 'OPTIONS']) - @controller.Controller.must_authorized() - def get_category_tree(self): - parent_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', False)], ['id', 'name']) - data = [] - for parent_category in parent_categories: - parent_data = { - 'id': parent_category['id'], - 'name': parent_category['name'], - 'childs': [] - } - child_1_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', parent_category['id'])], ['id', 'name']) - for child_1_category in child_1_categories: - child_1_data = { - 'id': child_1_category['id'], - 'name': child_1_category['name'], + class CategoryManagement(controller.Controller): + prefix = '/api/v1/' + + @http.route(prefix + 'category/tree', auth='public', methods=['GET', 'OPTIONS'], csrf=False) + @controller.Controller.must_authorized() + def get_category_tree(self): + parent_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', False)], + ['id', 'name', 'image_1920']) + data = [] + for parent_category in parent_categories: + category_data_ids = [parent_category['id']] + parent_data = { + 'id': parent_category['id'], + 'name': parent_category['name'], + 'image': request.env['ir.attachment'].sudo().api_image('product.public.category', 'image_1920', + parent_category['id']), + 'category_data_ids': category_data_ids, 'childs': [] } - child_2_categories = request.env['product.public.category'].search_read([('parent_frontend_id', '=', child_1_category['id'])], ['id', 'name']) - for child_2_category in child_2_categories: - child_2_data = { - 'id': child_2_category['id'], - 'name': child_2_category['name'], + child_1_categories = request.env['product.public.category'].search_read( + [('parent_frontend_id', '=', parent_category['id'])], ['id', 'name']) + for child_1_category in child_1_categories: + child_1_data = { + 'id': child_1_category['id'], + 'name': child_1_category['name'], + 'childs': [] } - child_1_data['childs'].append(child_2_data) - parent_data['childs'].append(child_1_data) - data.append(parent_data) - return self.response(data, headers=[('Cache-Control', 'max-age=3600, public')]) + category_data_ids.append(child_1_category['id']) + child_2_categories = request.env['product.public.category'].search_read( + [('parent_frontend_id', '=', child_1_category['id'])], ['id', 'name']) + for child_2_category in child_2_categories: + child_2_data = { + 'id': child_2_category['id'], + 'name': child_2_category['name'], + } + child_1_data['childs'].append(child_2_data) + category_data_ids.append(child_2_category['id']) + parent_data['childs'].append(child_1_data) + parent_data['category_data_ids'] = category_data_ids + data.append(parent_data) + return self.response(data, headers=[('Cache-Control', 'max-age=3600, public')]) @http.route(prefix + 'categories_homepage/ids', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py index a6e14a19..69a2f861 100644 --- a/indoteknik_api/controllers/api_v1/partner.py +++ b/indoteknik_api/controllers/api_v1/partner.py @@ -142,9 +142,12 @@ class Partner(controller.Controller): partner_industry = request.env['res.partner.industry'].search([]) data = [] for industry in partner_industry: + full_name = industry.full_name + category = full_name.title() if full_name else '-' data.append({ 'id': industry.id, - 'name': industry.name + 'name': industry.name, + 'category': category }) return self.response(data) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 0da7f894..b351bacc 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -403,20 +403,21 @@ class SaleOrder(controller.Controller): 'shipping_paid_by': 'customer', 'carrier_id': params['value']['carrier_id'], 'delivery_service_type': params['value']['delivery_service_type'], - 'flash_sale': params['value']['flash_sale'], + 'flash_sale': params['value']['flash_sale'], 'note_website': params['value']['note_website'], 'customer_type': 'nonpkp', 'npwp': '0', 'user_id': 3222 # User ID: Nadia Rauhadatul Firdaus } + + sales_partner = request.env['res.partner'].browse(parameters['partner_id']) + if sales_partner and sales_partner.user_id and sales_partner.user_id.id not in [25]: # 25: System + parameters['user_id'] = sales_partner.user_id.id + if params['value']['type'] == 'sale_order': parameters['approval_status'] = 'pengajuan1' sale_order = request.env['sale.order'].create([parameters]) sale_order.onchange_partner_contact() - - sales_partner = sale_order.partner_id.user_id - if sales_partner and sales_partner not in [25]: # 25: System - parameters['user_id'] = sales_partner.id user_id = params['value']['user_id'] user_cart = request.env['website.user.cart'] diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py index 9b89e82c..b9fd9f56 100644 --- a/indoteknik_api/controllers/api_v1/user.py +++ b/indoteknik_api/controllers/api_v1/user.py @@ -1,3 +1,5 @@ +import base64 + from .. import controller from odoo import http from odoo.http import request @@ -104,10 +106,10 @@ class User(controller.Controller): password = kw.get('password') if not name or not email or not password: return self.response(code=400, description='email, name and password is required') - + company = kw.get('company', False) phone = kw.get('phone') - + response = { 'register': False, 'reason': None @@ -120,7 +122,7 @@ class User(controller.Controller): else: user.send_activation_mail() response['reason'] = 'NOT_ACTIVE' - + return self.response(response) user_data = { diff --git a/indoteknik_custom/models/approval_date_doc.py b/indoteknik_custom/models/approval_date_doc.py index e00b7416..441ada3d 100644 --- a/indoteknik_custom/models/approval_date_doc.py +++ b/indoteknik_custom/models/approval_date_doc.py @@ -16,10 +16,12 @@ class ApprovalDateDoc(models.Model): string='Driver Departure Date', copy=False ) - state = fields.Selection([('draft', 'Draft'), ('done', 'Done')], string='State', default='draft', tracking=True) + state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancel')], string='State', default='draft', tracking=True) approve_date = fields.Datetime(string='Approve Date', copy=False) approve_by = fields.Many2one('res.users', string='Approve By', copy=False) sale_id = fields.Many2one('sale.order', string='Sale Order') + partner_id = fields.Many2one('res.partner', string='Partner', related='picking_id.partner_id') + note = fields.Char(string='Note') @api.onchange('picking_id') def onchange_picking_id(self): @@ -42,6 +44,9 @@ class ApprovalDateDoc(models.Model): self.approve_date = datetime.utcnow() self.approve_by = self.env.user.id + def button_cancel(self): + self.state = 'cancel' + @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('approval.date.doc') or '0' diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py index f5b1baf9..3561fc0f 100644 --- a/indoteknik_custom/models/automatic_purchase.py +++ b/indoteknik_custom/models/automatic_purchase.py @@ -545,6 +545,37 @@ class AutomaticPurchaseLine(models.Model): def _calculate_subtotal(self): for line in self: line.subtotal = line.qty_purchase * line.last_price + + @api.onchange('product_id') + def _onchange_product_id(self): + for line in self: + purchase_price = self.env['purchase.pricelist'].search([ + ('product_id', '=', line.product_id.id), + ('vendor_id', '=', line.partner_id.id) + ], order='count_trx_po desc, count_trx_po_vendor desc', limit=1) + vendor_id = purchase_price.vendor_id.id + price, taxes = self._get_valid_purchase_price(purchase_price) + line.last_price = price + line.taxes_id = taxes + line.brand_id = line.product_id.product_tmpl_id.x_manufacture.id + line.partner_id = vendor_id + + def _get_valid_purchase_price(self, purchase_price): + price = 0 + taxes = '' + human_last_update = purchase_price.human_last_update or datetime.min + system_last_update = purchase_price.system_last_update or datetime.min + + if purchase_price.taxes_product_id.type_tax_use == 'purchase': + price = purchase_price.product_price + taxes = purchase_price.taxes_product_id.id + + if system_last_update > human_last_update: + if purchase_price.taxes_system_id.type_tax_use == 'purchase': + price = purchase_price.system_price + taxes = purchase_price.taxes_system_id.id + + return price, taxes class AutomaticPurchaseMatch(models.Model): diff --git a/indoteknik_custom/models/midtrans.py b/indoteknik_custom/models/midtrans.py index c99c8410..6acbe5a7 100644 --- a/indoteknik_custom/models/midtrans.py +++ b/indoteknik_custom/models/midtrans.py @@ -39,6 +39,10 @@ class MidtransNotification(models.Model): orders = order_id.split('_') order = orders[0].replace('-', '/') + + if 'cpl' in order_id: + order = order.replace('/cpl', '') + sale_order = self.env['sale.order'].search([('name', '=', order)], limit=1) notif.payment_status = payment_status diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index 56460821..e6778758 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -61,6 +61,12 @@ class ProductTemplate(models.Model): tkdn = fields.Boolean(string='TKDN') short_spesification = fields.Char(string='Short Spesification') + @api.constrains('name', 'internal_reference', 'x_manufacture') + def required_public_categ_ids(self): + for rec in self: + if not rec.public_categ_ids: + raise UserError('Field Categories harus diisi') + def _get_qty_sold(self): for rec in self: rec.qty_sold = sum(x.qty_sold for x in rec.product_variant_ids) @@ -337,7 +343,7 @@ class ProductTemplate(models.Model): raise UserError('Tidak dapat mengubah produk sementara') return super(ProductTemplate, self).write(vals) - + class ProductProduct(models.Model): _inherit = "product.product" web_price = fields.Float( @@ -367,6 +373,24 @@ class ProductProduct(models.Model): qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold') short_spesification = fields.Char(string='Short Spesification') + @api.constrains('name', 'internal_reference', 'x_manufacture') + def required_public_categ_ids(self): + for rec in self: + if not rec.public_categ_ids: + raise UserError('Field Categories harus diisi') + + @api.constrains('active') + def archive_product(self): + for product in self: + product_template = product.product_tmpl_id + variants = product_template.product_variant_ids + + if product_template.active and product.active: + if not product.active and len(variants) == 1: + product_template.with_context(skip_active_constraint=True).active = False + elif not product.active and len(variants) > 1: + continue + def update_internal_reference_variants(self, limit=100): variants = self.env['product.product'].search([ ('default_code', '=', False), diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index c6512772..8ec904a9 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -434,6 +434,8 @@ class PurchaseOrder(models.Model): def button_confirm(self): res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() + self.check_ppn_mix() + # self.check_data_vendor() 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") @@ -477,9 +479,22 @@ class PurchaseOrder(models.Model): self.date_planned = delta_time self.date_deadline_ref_date_planned() self.unlink_purchasing_job_state() + return res + def check_ppn_mix(self): + reference_taxes = self.order_line[0].taxes_id + + for line in self.order_line: + if line.taxes_id != reference_taxes: + raise UserError("PPN harus sama untuk semua baris pada line.") + + def check_data_vendor(self): + vendor = self.partner_id + if not vendor.email_finance or not vendor.email_sales: + raise UserError("Email Finance dan Email Sales pada vendor harus diisi") + def unlink_purchasing_job_state(self): for line in self.order_line: purchasing_job_state = self.env['purchasing.job.state'].search([ diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 0b0a679f..710e99de 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -277,7 +277,7 @@ class SaleOrder(models.Model): if check_response.status_code == 200: status_response = check_response.json() - if status_response.get('transaction_status') == 'expire': + if status_response.get('transaction_status') == 'expire' or status_response.get('transaction_status') == 'cancel': so_number = so_number + '-cpl' json_data = { @@ -507,6 +507,8 @@ class SaleOrder(models.Model): raise UserError("SPPKP berbeda pada Master Data Customer") if not order.client_order_ref and order.create_date > datetime(2024, 6, 27): raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO") + if not order.user_id.active: + raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact") def sale_order_approve(self): self.check_due() @@ -528,6 +530,8 @@ class SaleOrder(models.Model): raise UserError("SPPKP berbeda pada Master Data Customer") if not order.client_order_ref and order.create_date > datetime(2024, 6, 27): raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO") + if not order.user_id.active: + raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact") if order.validate_partner_invoice_due(): return self._create_notification_action('Notification', 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension') @@ -878,7 +882,7 @@ class SaleOrder(models.Model): ('order_id.date_order', '>=', delta_time) ], limit=1, order='create_date desc') - if rec_vendor_id != last_so.vendor_id.id: + if last_so and rec_vendor_id != last_so.vendor_id.id: last_so = self.env['sale.order.line'].search([ # ('order_id.partner_id.id', '=', order_line.order_id.partner_id.id), ('order_id.partner_id', 'in', partners), @@ -889,7 +893,7 @@ class SaleOrder(models.Model): ('order_id.date_order', '>=', delta_time) ], limit=1, order='create_date desc') - if rec_purchase_price != last_so.purchase_price: + if last_so and rec_purchase_price != last_so.purchase_price: rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1) if rec_taxes.price_include: selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100)) @@ -911,7 +915,7 @@ class SaleOrder(models.Model): tax_id = order_line.tax_id discount = order_line.discount - elif rec_vendor_id == order_line.vendor_id.id and rec_purchase_price != last_so.purchase_price: + elif last_so and rec_vendor_id == order_line.vendor_id.id and rec_purchase_price != last_so.purchase_price: rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1) if rec_taxes.price_include: selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100)) diff --git a/indoteknik_custom/models/solr/__init__.py b/indoteknik_custom/models/solr/__init__.py index 925a8c14..606c0035 100644 --- a/indoteknik_custom/models/solr/__init__.py +++ b/indoteknik_custom/models/solr/__init__.py @@ -5,7 +5,6 @@ from . import product_pricelist_item from . import product_product from . import product_template from . import website_categories_homepage -from . import website_categories_management from . import x_manufactures from . import x_banner_banner from . import product_public_category diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index f09c2dfb..35e3a4b3 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -57,7 +57,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.template', 'image_256', variant.product_tmpl_id.id), + 'image_s': ir_attachment.api_image('product.template', 'image_512', variant.product_tmpl_id.id), 'stock_total_f': variant.qty_stock_vendor, 'weight_f': variant.weight, 'manufacture_id_i': variant.product_tmpl_id.x_manufacture.id or 0, @@ -65,6 +65,7 @@ class ProductProduct(models.Model): 'manufacture_name': variant.product_tmpl_id.x_manufacture.x_name or '', '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), + 'x_logo_manufacture_s': ir_attachment.api_image('x_manufactures', 'x_logo_manufacture', 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 6ad49af7..6f76c529 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -77,7 +77,6 @@ class ProductTemplate(models.Model): ]) is_in_bu = bool(stock_quant) - on_hand_qty = sum(stock_quant.mapped('quantity')) if stock_quant else 0 document = solr_model.get_doc('product', template.id) document.update({ @@ -87,7 +86,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_256', template.id), + "image_s": self.env['ir.attachment'].api_image('product.template', 'image_512', template.id), "variant_total_i": template.product_variant_count, "stock_total_f": template.qty_stock_vendor, "weight_f": template.weight, @@ -96,6 +95,7 @@ class ProductTemplate(models.Model): "manufacture_name": template.x_manufacture.x_name or '', "image_promotion_1_s": self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_1', template.x_manufacture.id), "image_promotion_2_s": self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_2', template.x_manufacture.id), + 'x_logo_manufacture_s': self.env['ir.attachment'].api_image('x_manufactures', 'x_logo_manufacture', template.x_manufacture.id), "variants_name_t": variant_names, "variants_code_t": variant_codes, "search_rank_i": template.search_rank, @@ -110,13 +110,10 @@ class ProductTemplate(models.Model): 'tkdn_b': template.unpublished, "qty_sold_f": template.qty_sold, "is_in_bu_b": is_in_bu, - "on_hand_qty_i": on_hand_qty, - "voucher_pastihemat" : { - "min_purchase" : voucher.min_purchase_amount or 0, - "discount_type" : voucher.discount_type or '', - "discount_amount" : voucher.discount_amount or 0, - "max_discount" : voucher.max_discount_amount or 0 - } + "voucher_min_purchase_f" : voucher.min_purchase_amount or 0, + "voucher_discount_type_s" : voucher.discount_type or '', + "voucher_discount_amount_f" : voucher.discount_amount or 0, + "voucher_max_discount_f" : voucher.max_discount_amount or 0 }) self.solr().add(docs=[document], softCommit=True) diff --git a/indoteknik_custom/models/solr/website_categories_management.py b/indoteknik_custom/models/solr/website_categories_management.py deleted file mode 100644 index 49f52378..00000000 --- a/indoteknik_custom/models/solr/website_categories_management.py +++ /dev/null @@ -1,95 +0,0 @@ -from odoo import models, fields, api -from datetime import datetime -import json - -import logging - -_logger = logging.getLogger(__name__) - - -class WebsiteCategoriesManagement(models.Model): - _inherit = 'website.categories.management' - - last_update_solr = fields.Datetime('Last Update Solr') - - def solr(self): - return self.env['apache.solr'].connect('product_category_management') - - def update_last_update_solr(self): - self.last_update_solr = datetime.utcnow() - - def _create_solr_queue(self, function_name): - for rec in self: - self.env['apache.solr.queue'].create_unique({ - 'res_model': self._name, - 'res_id': rec.id, - 'function_name': function_name - }) - - @api.constrains('status') - def _create_solr_queue_sync_status(self): - self._create_solr_queue('_sync_status_category_management_solr') - - @api.constrains('category_id', 'sequence', 'category_id2') - def _create_solr_queue_sync_category_homepage(self): - self._create_solr_queue('_sync_category_management_to_solr') - - def action_sync_to_solr(self): - category_ids = self.env.context.get('active_ids', []) - categories = self.search([('id', 'in', category_ids)]) - categories._create_solr_queue('_sync_category_management_to_solr') - - def unlink(self): - res = super(WebsiteCategoriesManagement, self).unlink() - for rec in self: - self.solr().delete(rec.id) - self.solr().optimize() - self.solr().commit() - return res - - def _sync_status_category_management_solr(self): - for rec in self: - if rec.status == 'tayang': - rec._sync_category_management_to_solr() - else: - rec.unlink() - - def _sync_category_management_to_solr(self): - solr_model = self.env['apache.solr'] - - for category in self: - if category.status == 'tidak_tayang': - continue - - category_id2_data = [ - { - 'id_level_2': x.id, - 'name': x.name, - 'image': x.image, - 'child_frontend_id_i': [{'id_level_3': child.id, 'name': child.name, 'image': child.image} for child in - x.child_frontend_id2] - } - for x in category.category_id2 - ] - category_id2_json = json.dumps(category_id2_data) - document = solr_model.get_doc('product_category_management', category.id) - document.update({ - 'id': category.id, - 'category_id_i': category.category_id.id, - 'image_s': self.env['ir.attachment'].api_image('product.public.category', 'image_1920', category.category_id.id), - 'name_s': category.category_id.name, - 'sequence_i': category.sequence or '', - 'category_id2_s': category_id2_json, - }) - _logger.info('Category %s synchronized to Solr with document: %s', document) - _logger.info('Category %s synchronized to Solr with category_id2_json: %s', category_id2_json) - self.solr().add([document]) - category.update_last_update_solr() - - self.solr().commit() - - # def _sync_delete_solr(self): - # for rec in self: - # self.solr().delete(rec.id) - # self.solr().optimize() - # self.solr().commit()
\ No newline at end of file diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 5029a770..6083e9e7 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -107,8 +107,9 @@ class StockPicking(models.Model): @api.constrains('arrival_time') def constrains_arrival_time(self): - if self.arrival_time > datetime.datetime.utcnow(): - raise UserError('Jam kedatangan harus kurang dari Effective Date') + for record in self: + if record.arrival_time and record.arrival_time > datetime.datetime.utcnow(): + raise UserError('Jam kedatangan harus kurang dari Effective Date') def reset_status_printed(self): for rec in self: diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index c21ef209..f7305999 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -52,6 +52,7 @@ class Voucher(models.Model): terms_conditions = fields.Html('Terms and Conditions') apply_type = fields.Selection(string='Apply Type', default="all", selection=[ ('all', "All product"), + ('shipping', "Shipping"), ('brand', "Selected product brand"), ]) count_order = fields.Integer(string='Count Order', compute='_compute_count_order') diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 10821cd3..d9352abb 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -145,14 +145,15 @@ class WebsiteUserCart(models.Model): } return result - def action_mail_reminder_to_checkout(self): - user_ids = self.search([]).mapped('user_id') + def action_mail_reminder_to_checkout(self, limit=10): + user_ids = self.search([]).mapped('user_id')[:limit] - # user_ids = [1102] - for user in user_ids: + for user in user_ids: latest_cart = self.search([('user_id', '=', user.id), ('is_reminder', '=', False)], order='create_date desc', limit=1) + # Proses semua keranjang untuk user tersebut carts_to_remind = self.search([('user_id', '=', user.id)]) + if latest_cart and not latest_cart.is_reminder: for cart in carts_to_remind: check = cart.check_product_flashsale(cart.product_id.id) @@ -161,9 +162,12 @@ class WebsiteUserCart(models.Model): if cart.program_line_id or check['is_flashsale'] or cart.product_id.default_code and 'BOM' in cart.product_id.default_code: cart.is_selected = False cart.is_reminder = True + + # Mengirim email pengingat untuk keranjang terbaru template = self.env.ref('indoteknik_custom.mail_template_user_cart_reminder_to_checkout') template.send_mail(latest_cart.id, force_send=True) + def calculate_discount(self, user_id): carts = self.search([('user_id', '=', user_id)]) voucher = self.env['voucher'].browse(146) diff --git a/indoteknik_custom/views/approval_date_doc.xml b/indoteknik_custom/views/approval_date_doc.xml index d6a70763..3d597aa8 100644 --- a/indoteknik_custom/views/approval_date_doc.xml +++ b/indoteknik_custom/views/approval_date_doc.xml @@ -7,11 +7,13 @@ <tree> <field name="number"/> <field name="picking_id"/> + <field name="partner_id"/> <field name="sale_id"/> <field name="driver_departure_date"/> <field name="state"/> <field name="approve_date"/> <field name="approve_by"/> + <field name="create_uid"/> </tree> </field> </record> @@ -27,16 +29,24 @@ type="object" attrs="{'invisible': [('state', '=', 'done')]}" /> + <button name="button_cancel" + string="Cancel" + type="object" + attrs="{'invisible': [('state', '=', 'cancel')]}" + /> </header> <sheet string="Approval Date Doc"> <group> <group> <field name="number"/> <field name="picking_id"/> + <field name="partner_id"/> <field name="sale_id"/> <field name="driver_departure_date"/> <field name="approve_date"/> <field name="approve_by"/> + <field name="create_uid"/> + <field name="note" attrs="{'invisible': [('state', '!=', 'cancel')]}"/> <field name="state" readonly="1"/> </group> </group> diff --git a/indoteknik_custom/views/automatic_purchase.xml b/indoteknik_custom/views/automatic_purchase.xml index cdaf6297..23aa1973 100644 --- a/indoteknik_custom/views/automatic_purchase.xml +++ b/indoteknik_custom/views/automatic_purchase.xml @@ -24,7 +24,7 @@ <tree editable="bottom"> <field name="brand_id"/> <field name="product_id"/> - <field name="taxes_id"/> + <field name="taxes_id" domain="[('type_tax_use','=','purchase')]"/> <field name="qty_purchase"/> <field name="qty_min"/> <field name="qty_max"/> @@ -32,7 +32,7 @@ <field name="qty_purchase"/> <field name="partner_id" required="1"/> <field name="last_price"/> - <field name="taxes_id"/> + <field name="taxes_id" domain="[('type_tax_use','=','purchase')]"/> <field name="subtotal"/> <field name="last_order_id" readonly="1" optional="hide"/> <field name="current_po_line_id" readonly="1" optional="hide"/> diff --git a/indoteknik_custom/views/product_template.xml b/indoteknik_custom/views/product_template.xml index 520af5c8..e3a39412 100755 --- a/indoteknik_custom/views/product_template.xml +++ b/indoteknik_custom/views/product_template.xml @@ -21,6 +21,9 @@ <field name="desc_update_solr" readonly="1" /> <field name="last_update_solr" readonly="1" /> </field> + <field name="public_categ_ids" position="attributes"> + <attribute name="required">1</attribute> + </field> <page name="inventory" position="after"> <page string="Marketplace" name="marketplace"> <group> diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml index 71c0df0b..29d0ad4b 100755 --- a/indoteknik_custom/views/voucher.xml +++ b/indoteknik_custom/views/voucher.xml @@ -38,9 +38,9 @@ <field name="show_on_email" /> <field name="excl_pricelist_ids" widget="many2many_tags" domain="[('id', 'in', [4, 15037, 15038, 15039, 17023, 17024, 17025, 17026,17027])]"/> </group> - <group string="Discount Settings" attrs="{'invisible': [('apply_type', '!=', 'all')]}"> + <group string="Discount Settings" attrs="{'invisible': [('apply_type', 'not in', ['all', 'shipping'])]}"> <field name="min_purchase_amount" widget="monetary" required="1" /> - <field name="discount_type" attrs="{'invisible': [('apply_type','!=','all')], 'required': [('apply_type', '=', 'all')]}" /> + <field name="discount_type" attrs="{'invisible': [('apply_type','not in', ['all', 'shipping'])], 'required': [('apply_type', 'in', ['all', 'shipping'])]}" /> <label for="max_discount_amount" string="Discount Amount" /> <div class="d-flex align-items-center"> |
