diff options
Diffstat (limited to 'indoteknik_custom/models')
23 files changed, 331 insertions, 108 deletions
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 720a4f91..9d8b9bea 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -106,3 +106,6 @@ from . import stock_quant from . import po_multi_cancel from . import logbook_sj from . import report_logbook_sj +from . import role_permission +from . import cust_commision +from . import report_stock_forecasted diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index a9db212f..7eb65e9f 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -122,7 +122,7 @@ class AccountMove(models.Model): sum_qty_invoice = sum_qty_order = 0 for line in purchase_order.order_line: sum_qty_invoice += line.qty_invoiced - sum_qty_order += line.product_uom_qty + sum_qty_order += line.product_qty if sum_qty_invoice > sum_qty_order: raise UserError('Error Qty Invoice akan lebih besar dari Qty Order jika lanjut Posting') diff --git a/indoteknik_custom/models/base_import_import.py b/indoteknik_custom/models/base_import_import.py index 6a100cb8..01e02a4a 100644 --- a/indoteknik_custom/models/base_import_import.py +++ b/indoteknik_custom/models/base_import_import.py @@ -56,7 +56,10 @@ class Import(models.TransientModel): raise UserError(message) def do(self, fields, columns, options, dryrun=False): - enable_import = self._check_enable_import() - if not enable_import: - self._unable_import_notif() + model = self.res_model + can_import = self.env.user.check_access(model, 'import') + + if not can_import: + raise UserError('You are not allowed to import') + return super(Import, self).do(fields, columns, options, dryrun) diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py index 955d1634..094aa66e 100644 --- a/indoteknik_custom/models/commision.py +++ b/indoteknik_custom/models/commision.py @@ -156,7 +156,17 @@ class CustomerCommision(models.Model): # add status for type of commision, fee, rebate / cashback # include child or not? - @api.constrains('commision_percent') + @api.constrains('partner_ids') + def _onchange_partner_ids(self): + commision = self.env['cust.commision'].search([ + ('partner_id', 'in', [rec.id for rec in self.partner_ids]), + ]) + + if commision: + max_commision = max(commision.mapped('commision_percent')) + self.commision_percent = max_commision + + @api.constrains('commision_percent', 'partner_ids') def _onchange_commision_percent(self): print('masuk onchange commision percent') if self.commision_amt == 0: @@ -165,8 +175,8 @@ class CustomerCommision(models.Model): @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) + if self.total_dpp > 0: + self.commision_percent = (self.commision_amt / self.total_dpp) * 100 def _compute_total_dpp(self): for data in self: @@ -208,6 +218,9 @@ class CustomerCommision(models.Model): else: self._generate_customer_commision_rebate() + self._onchange_commision_percent() + self._onchange_commision_amt() + def _generate_customer_commision_rebate(self): for rec in self: # partners = rec.partner_ids.child_ids + rec.partner_ids diff --git a/indoteknik_custom/models/cust_commision.py b/indoteknik_custom/models/cust_commision.py new file mode 100644 index 00000000..eeb255cd --- /dev/null +++ b/indoteknik_custom/models/cust_commision.py @@ -0,0 +1,25 @@ +from odoo import models, api, fields +from odoo.exceptions import UserError +from datetime import datetime +import logging + +_logger = logging.getLogger(__name__) + + +class CustCommision(models.Model): + _name = 'cust.commision' + _order = 'id desc' + + partner_id = fields.Many2one('res.partner', String='Customer', required=True) + commision_percent = fields.Float(string='Commision %', tracking=3) + + @api.constrains('partner_id') + def _check_partner_id(self): + for rec in self: + duplicate_partner = self.search([ + ('partner_id', '=', rec.partner_id.id), + ('id', '!=', rec.id) + ]) + if duplicate_partner: + raise UserError('Partner already exists') +
\ No newline at end of file diff --git a/indoteknik_custom/models/logbook_sj.py b/indoteknik_custom/models/logbook_sj.py index 567f1ae3..bf4acd14 100644 --- a/indoteknik_custom/models/logbook_sj.py +++ b/indoteknik_custom/models/logbook_sj.py @@ -18,31 +18,27 @@ class LogbookSJ(models.TransientModel): current_time = datetime.utcnow() report_logbook_ids = [] + parameters_header = { + 'date': current_time, + } + + report_logbook = self.env['report.logbook.sj'].create([parameters_header]) 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, + picking = self.env['stock.picking'].search([('picking_code', '=', line.name)], limit=1) + stock = picking + + data = { + 'picking_id': stock.id, + 'name': stock.name, + 'driver_id': stock.driver_id.id, + 'departure_date': stock.driver_departure_date, + 'arrival_date': stock.driver_arrival_date, + 'carrier_id': stock.carrier_id.id, + 'tracking_no': stock.delivery_tracking_no, + 'partner_id': stock.partner_id.id, + 'report_logbook_sj_id': report_logbook.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]) + self.env['report.logbook.sj.line'].create([data]) report_logbook_ids.append(report_logbook.id) line.unlink() @@ -68,6 +64,7 @@ class LogbookSJLine(models.TransientModel): 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') + picking_id = fields.Many2one('res.partner', string='Customer') @api.onchange('name') def onchange_name(self): @@ -94,6 +91,8 @@ class LogbookSJLine(models.TransientModel): self.partner_id = picking.partner_id + self.picking_id = picking.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') diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index d2fa793a..4bab2cad 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -74,34 +74,27 @@ class ProductTemplate(models.Model): @api.constrains('name', 'default_code') def _check_duplicate_product(self): for product in self: - 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)] + variants = product.product_variant_ids + names = [x.name for x in variants] if variants else [product.name] + default_codes = [x.default_code for x in variants] if variants else [product.default_code] - 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 = [ + ('default_code', '!=', False), + ('id', '!=', product.id), + '|', + ('name', 'in', names), + ('default_code', 'in', default_codes) + ] + + product_exist = self.search(domain, limit=1) + if len(product_exist) > 0: + raise UserError('Name atau Internal Reference sudah digunakan pada produk lain') - domain.append(('id', '!=', product.id)) + 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: - 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) + if sum(product.day_product_to_edit()) > 0: + raise UserError('Produk ini tidak dapat diubah') @api.constrains('name') def _validate_name(self): @@ -382,30 +375,6 @@ class ProductProduct(models.Model): day_products.append(day_product) return day_products - - @api.constrains('name','default_code') - def _check_duplicate_product(self): - for product in self: - 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): diff --git a/indoteknik_custom/models/promotion/__init__.py b/indoteknik_custom/models/promotion/__init__.py index 1e15d714..82628d31 100644 --- a/indoteknik_custom/models/promotion/__init__.py +++ b/indoteknik_custom/models/promotion/__init__.py @@ -5,4 +5,5 @@ from . import promotion_free_product from . import sale_order_promotion from . import sale_order_line from . import sale_order -from . import promotion_keyword
\ No newline at end of file +from . import promotion_keyword +from . import promotion_monitoring
\ No newline at end of file diff --git a/indoteknik_custom/models/promotion/promotion_free_product.py b/indoteknik_custom/models/promotion/promotion_free_product.py index c5055562..e91d5137 100644 --- a/indoteknik_custom/models/promotion/promotion_free_product.py +++ b/indoteknik_custom/models/promotion/promotion_free_product.py @@ -17,6 +17,10 @@ class PromotionFreeProduct(models.Model): weight = rec.product_id.weight or 0 result.append({ 'id': rec.product_id.id, + 'parent': { + 'id': rec.product_id.product_tmpl_id.id, + 'name': rec.product_id.product_tmpl_id.name, + }, 'image': ir_attachment.api_image('product.template', 'image_256', rec.product_id.product_tmpl_id.id), 'display_name': rec.product_id.display_name, 'name': rec.product_id.name, diff --git a/indoteknik_custom/models/promotion/promotion_monitoring.py b/indoteknik_custom/models/promotion/promotion_monitoring.py new file mode 100644 index 00000000..9df0825d --- /dev/null +++ b/indoteknik_custom/models/promotion/promotion_monitoring.py @@ -0,0 +1,45 @@ +from odoo import fields, models, tools + + +class PromotionMonitoring(models.Model): + _name = "promotion.monitoring" + _auto = False + _rec_name = "product_id" + + product_id = fields.Many2one(comodel_name="product.product", string="Product") + manufacture_id = fields.Many2one(comodel_name="x_manufactures", string="Manufacture", related="product_id.x_manufacture") + price = fields.Float(string="Price", help="Computed Price di Product Pricelist (Tier 1 New)") + has_promo = fields.Boolean(string="Has Promo") + count_active = fields.Integer(string="Count Active") + count_inactive = fields.Integer(string="Count Inactive") + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + sql = { + 'count_active': "COUNT(CASE WHEN ppl.active = True THEN ppl.id ELSE NULL END)", + 'count_inactive': "COUNT(CASE WHEN ppl.active = False THEN ppl.id ELSE NULL END)" + } + self.env.cr.execute(""" + CREATE OR REPLACE VIEW {table} AS ( + SELECT + p.id as id, + p.id as product_id, + ppi.computed_price as price, + ({count_active} > 0) as has_promo, + {count_active} as count_active, + {count_inactive} as count_inactive + FROM product_product p + LEFT JOIN product_template pt ON pt.id = p.product_tmpl_id + LEFT JOIN promotion_product pp ON pp.product_id = p.id + LEFT JOIN promotion_program_line ppl ON ppl.id = pp.program_line_id + LEFT JOIN product_pricelist_item ppi ON ppi.product_id = p.id + WHERE p.active = True + AND pt.sale_ok = True + AND ppi.pricelist_id = 17023 + GROUP BY p.id, ppi.id + ) + """.format( + table=self._table, + count_active=sql['count_active'], + count_inactive=sql['count_inactive'] + ))
\ No newline at end of file diff --git a/indoteknik_custom/models/promotion/promotion_product.py b/indoteknik_custom/models/promotion/promotion_product.py index 2fad0f0d..ae26e888 100644 --- a/indoteknik_custom/models/promotion/promotion_product.py +++ b/indoteknik_custom/models/promotion/promotion_product.py @@ -17,6 +17,10 @@ class PromotionProduct(models.Model): weight = rec.product_id.weight or 0 result.append({ 'id': rec.product_id.id, + 'parent': { + 'id': rec.product_id.product_tmpl_id.id, + 'name': rec.product_id.product_tmpl_id.name, + }, 'image': ir_attachment.api_image('product.template', 'image_256', rec.product_id.product_tmpl_id.id), 'display_name': rec.product_id.display_name, 'name': rec.product_id.name, diff --git a/indoteknik_custom/models/promotion/promotion_program_line.py b/indoteknik_custom/models/promotion/promotion_program_line.py index 18a7e184..cb231889 100644 --- a/indoteknik_custom/models/promotion/promotion_program_line.py +++ b/indoteknik_custom/models/promotion/promotion_program_line.py @@ -30,6 +30,8 @@ class PromotionProgramLine(models.Model): discount_amount = fields.Float('Discount Amount') order_promotion_ids = fields.One2many('sale.order.promotion', 'program_line_id', 'Promotions') + active = fields.Boolean(string="Active", default=True) + solr_flag = fields.Integer(string="Solr Flag", default=1) def get_active_promotions(self, product_id): current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') @@ -74,6 +76,9 @@ class PromotionProgramLine(models.Model): } def _get_remaining_time(self): + if not self.program_id.end_time: + return 0 + calculate_time = self.program_id.end_time - datetime.now() return round(calculate_time.total_seconds()) @@ -93,9 +98,7 @@ class PromotionProgramLine(models.Model): free_products = self.free_product_ids.formats(purchase_qty=qty) merged_products = products + free_products - weight = 0 - if not any(x['package_weight'] == 0 for x in merged_products): - weight = sum(x['package_weight'] for x in merged_products) + weight = sum(x['package_weight'] for x in merged_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) diff --git a/indoteknik_custom/models/purchase_pricelist.py b/indoteknik_custom/models/purchase_pricelist.py index 67b22e4c..d9c9a51d 100755 --- a/indoteknik_custom/models/purchase_pricelist.py +++ b/indoteknik_custom/models/purchase_pricelist.py @@ -17,7 +17,7 @@ class PurchasePricelist(models.Model): 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', domain=[('type_tax_use', '=', 'purchase')]) - taxes_system_id = fields.Many2one('account.tax', string='Taxes System', readonly=True) + taxes_system_id = fields.Many2one('account.tax', string='Taxes System') include_price = fields.Float(string='Final Price', readonly=True) @api.depends('product_id', 'vendor_id') def _compute_name(self): diff --git a/indoteknik_custom/models/report_logbook_sj.py b/indoteknik_custom/models/report_logbook_sj.py index d2008608..5ff56c9a 100644 --- a/indoteknik_custom/models/report_logbook_sj.py +++ b/indoteknik_custom/models/report_logbook_sj.py @@ -6,29 +6,59 @@ 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') + name = fields.Char(string='Name', default='Logbook SJ') + date = fields.Datetime(string='Date Created') + date_approve = fields.Datetime(string='Date Approve') approve_by_finance = fields.Boolean(string='Approve By Finance') + approve_by = fields.Many2one(comodel_name='res.users', string='Approve By') report_logbook_sj_line = fields.One2many( comodel_name='report.logbook.sj.line', inverse_name='report_logbook_sj_id', string='Logbook SJ Line' ) + state = fields.Selection( + [('belum_terima', 'Belum Terima'), + ('terima_sebagian', 'Terima Sebagian'), + ('terima_semua', 'Sudah di terima semua'), + ], + default='terima_semua', + string='Status', + tracking=True + ) + + @api.model + def create(self, vals): + vals['name'] = self.env['ir.sequence'].next_by_code('report.logbook.sj') or '0' + result = super(ReportLogbookSJ, self).create(vals) + return result def approve(self): + current_time = datetime.utcnow() if self.env.user.is_accounting: self.approve_by_finance = True + self.date_approve = current_time + self.approve_by = self.env.user.id + if any(line.not_exist for line in self.report_logbook_sj_line): + if all(line.not_exist for line in self.report_logbook_sj_line): + self.state = 'belum_terima' + else: + self.state = 'terima_sebagian' + else: + self.state = 'terima_semua' 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 + 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('report.logbook.sj', string='Logbook SJ') # Corrected model name + partner_id = fields.Many2one('res.partner', string='Customer') + picking_id = fields.Many2one('stock.picking', string='Picking') + report_logbook_sj_id = fields.Many2one('report.logbook.sj', string='Logbook SJ') + not_exist = fields.Boolean(string='Not Exist') diff --git a/indoteknik_custom/models/report_stock_forecasted.py b/indoteknik_custom/models/report_stock_forecasted.py new file mode 100644 index 00000000..48a17095 --- /dev/null +++ b/indoteknik_custom/models/report_stock_forecasted.py @@ -0,0 +1,45 @@ +from odoo import api, models + +class ReplenishmentReport(models.AbstractModel): + _inherit = 'report.stock.report_product_product_replenishment' + + @api.model + def _get_report_lines(self, product_template_ids, product_variant_ids, wh_location_ids): + lines = super(ReplenishmentReport, self)._get_report_lines(product_template_ids, product_variant_ids, wh_location_ids) + + result_dict = {} + + for line in lines: + product_id = line.get('product', {}).get('id') + query = [('product_id', '=', product_id)] + document_out = line.get('document_out') + order_id = document_out.id if document_out else None + + if order_id: + result = self._calculate_result(line) + result_dict.setdefault(order_id, []).append(result) + + for order_id, results in result_dict.items(): + sale_order_lines = self.env['sale.order.line'].search([('order_id', '=', order_id)]) + + concatenated_result = ' ,'.join(results) + + for sale_order_line in sale_order_lines: + sale_order_line.reserved_from = concatenated_result + + return lines + + def _calculate_result(self, line): + if line['document_in']: + return str(line["document_in"].name) + elif line['reservation'] and not line['document_in']: + return 'Reserved from stock' + elif line['replenishment_filled']: + if line['document_out']: + return 'Inventory On Hand' + else: + return 'Free Stock' + else: + return 'Not Available' + + diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index 09321fc6..33f64ce3 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -39,3 +39,20 @@ class ResUsers(models.Model): if not vouchers: return None return ', '.join(x.code for x in vouchers) return None + + def check_access(self, model, mode): + assert mode in ('read', 'write', 'create', 'unlink', 'import', 'export'), 'Invalid access mode' + + self._cr.execute(""" + SELECT MAX(CASE WHEN perm_{mode} THEN 1 ELSE 0 END) + FROM ir_model_access a + JOIN ir_model m ON (m.id = a.model_id) + JOIN res_groups_users_rel gu ON (gu.gid = a.group_id) + WHERE m.model = %s + AND gu.uid = %s + AND a.active IS TRUE + """.format(mode=mode), (model, self._uid,)) + r = self._cr.fetchone()[0] + + return bool(r) + diff --git a/indoteknik_custom/models/role_permission/__init__.py b/indoteknik_custom/models/role_permission/__init__.py new file mode 100644 index 00000000..da36bc1e --- /dev/null +++ b/indoteknik_custom/models/role_permission/__init__.py @@ -0,0 +1 @@ +from . import ir_model_access
\ No newline at end of file diff --git a/indoteknik_custom/models/role_permission/ir_model_access.py b/indoteknik_custom/models/role_permission/ir_model_access.py new file mode 100644 index 00000000..c77e9b79 --- /dev/null +++ b/indoteknik_custom/models/role_permission/ir_model_access.py @@ -0,0 +1,9 @@ +from odoo import fields, models + + +class IrModelAccess(models.Model): + _inherit = 'ir.model.access' + + perm_import = fields.Boolean(string='Import Access') + perm_export = fields.Boolean(string='Export Access') +
\ No newline at end of file diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 362ca574..8b789976 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -453,6 +453,7 @@ class SaleOrder(models.Model): order.approval_status = 'approved' order._set_sppkp_npwp_contact() order.calculate_line_no() + # order.order_line.get_reserved_from() res = super(SaleOrder, self).action_confirm() return res diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 62f4a6b4..a140468c 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -29,6 +29,32 @@ class SaleOrderLine(models.Model): 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') + reserved_from = fields.Char(string='Reserved From', copy=False) + + # def get_reserved_from(self): + # for line in self: + # current_stock = self.env['stock.quant'].search([ + # ('product_id', '=', line.product_id.id), + # ('location_id', '=', line.order_id.warehouse_id.lot_stock_id.id) + # ]) + + # po_stock = self.env['purchase.order.line'].search([ + # ('product_id', '=', line.product_id.id), + # ('order_id.sale_order_id', '=', line.order_id.id), + # ('state', '=', 'done') + # ]) + + # available_quantity = current_stock.available_quantity if current_stock else 0 + # product_qty = po_stock.product_qty if po_stock else 0 + + # if available_quantity >= line.product_uom_qty: + # line.reserved_from = 'From Stock' + # elif product_qty >= line.product_uom_qty: + # line.reserved_from = 'From PO' + # elif (available_quantity + product_qty) >= line.product_uom_qty: + # line.reserved_from = 'From Stock and PO' + # else: + # line.reserved_from = None def _compute_qty_reserved(self): for line in self: @@ -41,6 +67,16 @@ class SaleOrderLine(models.Model): reserved_qty = sum(move.product_uom_qty for move in stock_moves) line.qty_reserved = reserved_qty + if reserved_qty > 0: + line._compute_reserved_from() + + + def _compute_reserved_from(self): + for line in self: + # continue + report_stock_forecasted = self.env['report.stock.report_product_product_replenishment'] + report_stock_forecasted._get_report_data(False, [line.product_id.id]) + 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/models/solr/apache_solr_queue.py b/indoteknik_custom/models/solr/apache_solr_queue.py index 07274295..1b51538f 100644 --- a/indoteknik_custom/models/solr/apache_solr_queue.py +++ b/indoteknik_custom/models/solr/apache_solr_queue.py @@ -18,6 +18,7 @@ class ApacheSolrQueue(models.Model): ('not_found', 'Record not found') ], 'Execute Status') execute_date = fields.Datetime('Execute Date') + description = fields.Text('Description') def _compute_display_name(self): for rec in self: @@ -38,6 +39,16 @@ class ApacheSolrQueue(models.Model): if elapsed_time > max_exec_time: break rec.execute_queue() + + def open_target_record(self): + return { + 'name': '', + 'view_mode': 'form', + 'res_model': self.res_model, + 'target': 'current', + 'type': 'ir.actions.act_window', + 'res_id': self.res_id + } def execute_queue(self): for rec in self: @@ -48,7 +59,8 @@ class ApacheSolrQueue(models.Model): _logger.info(f'Execute Queue: {res_model}.{function_name}() -> {res_id}') domain = [('id', '=', res_id)] - if res_model in ['product.template']: + model_incl_archive = ['product.template', 'promotion.program.line'] + if res_model in model_incl_archive: domain.append(('active', 'in', [True, False])) model_instance = self.env[res_model].search(domain) @@ -57,7 +69,8 @@ class ApacheSolrQueue(models.Model): rec.execute_status = 'success' else: rec.execute_status = 'not_found' - except: + except Exception as e: + rec.description = e rec.execute_status = 'failed' rec.execute_date = datetime.utcnow() self.env.cr.commit() diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index ac41dbff..c14f6b98 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -49,12 +49,6 @@ class ProductProduct(models.Model): 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, @@ -63,9 +57,9 @@ 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": image, + '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, + 'weight_f': variant.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 '', diff --git a/indoteknik_custom/models/solr/promotion_program_line.py b/indoteknik_custom/models/solr/promotion_program_line.py index 6e182324..9cd226fb 100644 --- a/indoteknik_custom/models/solr/promotion_program_line.py +++ b/indoteknik_custom/models/solr/promotion_program_line.py @@ -39,9 +39,8 @@ class PromotionProgramLine(models.Model): document.update({ 'id': rec.id, - 'program_id_i': rec.program_id.id, + 'program_id_i': rec.program_id.id or 0, 'name_s': rec.name, - 'image_s': self.env['ir.attachment'].api_image(self._name, 'image', rec.id) if rec.image else '', 'type_value_s': promotion_type['value'], 'type_label_s': promotion_type['label'], 'package_limit_i': rec.package_limit, @@ -53,10 +52,9 @@ class PromotionProgramLine(models.Model): 'free_product_ids': [x.product_id.id for x in rec.free_product_ids], '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]), + 'active_b': rec.active }) - self.solr().add([document]) - self.solr().commit() @api.model @@ -67,3 +65,13 @@ class PromotionProgramLine(models.Model): def write(self, vals): self._create_solr_queue('_sync_to_solr') return super(PromotionProgramLine, self).write(vals) + + def solr_flag_to_queue(self, limit=500): + domain = [ + ('solr_flag', '=', 2), + ('active', 'in', [True, False]) + ] + records = self.search(domain, limit=limit) + for record in records: + record._create_solr_queue('_sync_to_solr') + record.solr_flag = 1 |
