diff options
| -rw-r--r-- | indoteknik_api/controllers/api_v1/product.py | 15 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/sale_order.py | 3 | ||||
| -rw-r--r-- | indoteknik_api/models/sale_order.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/__manifest__.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/models/__init__.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/approval_retur_picking.py | 38 | ||||
| -rw-r--r-- | indoteknik_custom/models/requisition.py | 6 | ||||
| -rw-r--r-- | indoteknik_custom/models/sale_order_line.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/stock_picking.py | 36 | ||||
| -rw-r--r-- | indoteknik_custom/models/vendor_approval.py | 4 | ||||
| -rw-r--r-- | indoteknik_custom/models/website_user_cart.py | 2 | ||||
| -rwxr-xr-x | indoteknik_custom/security/ir.model.access.csv | 1 | ||||
| -rw-r--r-- | indoteknik_custom/views/approval_retur_picking.xml | 27 | ||||
| -rw-r--r-- | indoteknik_custom/views/requisition.xml | 8 |
14 files changed, 132 insertions, 12 deletions
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py index 9673b3ef..b68eb0f9 100644 --- a/indoteknik_api/controllers/api_v1/product.py +++ b/indoteknik_api/controllers/api_v1/product.py @@ -96,6 +96,21 @@ class Product(controller.Controller): return self.response(data, headers=[('Cache-Control', 'max-age=600, private')]) + @http.route(prefix + 'product_variant/<id>/qty_available', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def get_product_variant_stock_available_by_id(self, **kw): + id = int(kw.get('id')) + product = request.env['product.product'].search( + [('id', '=', id)], limit=1) + + qty_available = product.free_qty + + data = { + 'qty': qty_available, + } + + return self.response(data, headers=[('Cache-Control', 'max-age=600, private')]) + @http.route(prefix + 'product/template/price/<id>', auth='public', methods=['GET', 'OPTIONS']) def get_product_template_price_by_id(self, **kw): if not self.authenticate(): diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index e7664c79..905795b0 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -446,7 +446,8 @@ class SaleOrder(controller.Controller): 'company_id': 1, 'order_id': sale_order.id, 'product_id': cart['id'], - 'product_uom_qty': cart['quantity'] + 'product_uom_qty': cart['quantity'], + 'product_available_quantity': cart['available_quantity'] }) order_line.product_id_change() order_line.onchange_vendor_id() diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 725dbb4b..8e0371a3 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -84,6 +84,7 @@ class SaleOrder(models.Model): 'subtotal': line.price_subtotal } product['quantity'] = line.product_uom_qty + product['available_quantity'] = line.product_available_quantity data_with_detail['products'].append(product) for invoice in sale_order.invoice_ids: if invoice.state == 'posted': diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index c8a658b5..da44ebf3 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -145,6 +145,7 @@ 'views/approval_unreserve.xml', 'views/vendor_approval.xml', 'views/find_page.xml', + 'views/approval_retur_picking.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 e62fbb4a..4983cc17 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -131,3 +131,4 @@ from . import approval_unreserve from . import vendor_approval from . import partner from . import find_page +from . import approval_retur_picking diff --git a/indoteknik_custom/models/approval_retur_picking.py b/indoteknik_custom/models/approval_retur_picking.py new file mode 100644 index 00000000..34c449a8 --- /dev/null +++ b/indoteknik_custom/models/approval_retur_picking.py @@ -0,0 +1,38 @@ +from odoo import models, fields +import logging + +_logger = logging.getLogger(__name__) + + +class ApprovalReturPicking(models.TransientModel): + _name = 'approval.retur.picking' + _description = 'Wizard to add Note Return' + + note_return = fields.Text(string="Note Return") + + def action_confirm_note_return(self): + picking_ids = self._context.get('picking_ids') + picking = self.env['stock.picking'].browse(picking_ids) + + # Update the note_return field + picking.update({ + 'approval_return_status': 'pengajuan1' + }) + + # Post a highlighted message to lognote + # picking.message_post( + # body=f"<div style='background-color: #fdf2e9; border: 1px solid #f5c6cb; padding: 10px;'>" + # f"<b>Note Return (Pinned):</b><br>{self.note_return}</div>", + # subtype_id=self.env.ref("mail.mt_note").id + # ) + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': 'Notification', + 'message': 'Status pengajuan telah berubah', + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + diff --git a/indoteknik_custom/models/requisition.py b/indoteknik_custom/models/requisition.py index 3aa564df..32a9f94f 100644 --- a/indoteknik_custom/models/requisition.py +++ b/indoteknik_custom/models/requisition.py @@ -93,9 +93,9 @@ class Requisition(models.Model): def create_po_from_requisition(self): if not self.sales_approve: - raise UserError('Harus di Approve Vita') + raise UserError('Harus Di Approve oleh Vita') if not self.merchandise_approve: - raise UserError('Harus di Approve Darren') + raise UserError('Harus Di Approve oleh Darren') if not self.requisition_lines: raise UserError('Tidak ada Lines, belum bisa create PO') if self.is_po: @@ -168,7 +168,7 @@ class Requisition(models.Model): 'product_id': product.id, 'product_qty': line.qty_purchase, 'product_uom_qty': line.qty_purchase, - 'name': product.name, + 'name': product.display_name, 'price_unit': line.price_unit, 'taxes_id': tax, } diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 978b1f69..5a6640ec 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -31,6 +31,7 @@ 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') + product_available_quantity = fields.Float(string='Qty pickup by user',) reserved_from = fields.Char(string='Reserved From', copy=False) item_percent_margin_without_deduction = fields.Float('%Margin', compute='_compute_item_margin_without_deduction') weight = fields.Float(string='Weight') diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py index 1906dae0..50e9304b 100644 --- a/indoteknik_custom/models/stock_picking.py +++ b/indoteknik_custom/models/stock_picking.py @@ -104,6 +104,7 @@ class StockPicking(models.Model): ('to invoice', 'To Invoice'), ('no', 'Nothing to Invoice') ], string='Invoice Status', related="sale_id.invoice_status") + note_return = fields.Text(string="Note Return", help="Catatan untuk kirim barang kembali") state_reserve = fields.Selection([ ('waiting', 'Waiting For Fullfilment'), @@ -441,9 +442,28 @@ class StockPicking(models.Model): if self.env.user.is_accounting: pick.approval_return_status = 'approved' else: - pick.approval_return_status = 'pengajuan1' + if self.picking_type_code == 'outgoing': + if self.env.user.id in [3988, 3401, 20]: + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') + action['context'] = { + 'picking_ids': [x.id for x in self] + } + return action + else: + raise UserError('Harus Sales Admin yang Ask Return') + elif self.picking_type_code == 'incoming': + if self.env.user.has_group('indoteknik_custom.group_role_purchasing'): + action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard') + action['context'] = { + 'picking_ids': [x.id for x in self] + } + return action + else: + raise UserError('Harus Purchasing yang Ask Return') + def calculate_line_no(self): + for picking in self: name = picking.group_id.name for move in picking.move_ids_without_package: @@ -500,6 +520,10 @@ class StockPicking(models.Model): def button_validate(self): + if not self.env.user.is_logistic_approver and self.env.context.get('active_model') == 'stock.picking': + if self.origin and 'Return of' in self.origin: + raise UserError("Button ini hanya untuk Logistik") + if self._name != 'stock.picking': return super(StockPicking, self).button_validate() @@ -550,6 +574,14 @@ class StockPicking(models.Model): self.date_done = datetime.datetime.utcnow() self.state_reserve = 'done' return res + def action_cancel(self): + if not self.env.user.is_logistic_approver and self.env.context.get('active_model') == 'stock.picking': + if self.origin and 'Return of' in self.origin: + raise UserError("Button ini hanya untuk Logistik") + + res = super(StockPicking, self).action_cancel() + return res + @api.model def create(self, vals): @@ -685,4 +717,4 @@ class StockPicking(models.Model): formatted_fastest_eta = fastest_eta.strftime(format_time_fastest) formatted_longest_eta = longest_eta.strftime(format_time) - return f'{formatted_fastest_eta} - {formatted_longest_eta}' + return f'{formatted_fastest_eta} - {formatted_longest_eta}'
\ No newline at end of file diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py index b0d58b85..bcc5d3ea 100644 --- a/indoteknik_custom/models/vendor_approval.py +++ b/indoteknik_custom/models/vendor_approval.py @@ -30,10 +30,10 @@ class VendorApproval(models.Model): self.state = 'done' self.order_id.vendor_approval = True - self.order_id.action_confirm() message = "Vendor Approval approved by %s" % (self.env.user.name) self.order_id.message_post(body=message) - + if not self.order_id.due_id: + self.order_id.action_confirm() def action_reject(self): if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 6cb282f8..494f32f3 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -65,9 +65,11 @@ class WebsiteUserCart(models.Model): if stock_quant: res['is_in_bu'] = True res['on_hand_qty'] = sum(stock_quant.mapped('quantity')) + res['available_quantity'] = stock_quant.available_quantity else: res['is_in_bu'] = False res['on_hand_qty'] = 0 + res['available_quantity'] = 0 flashsales = self.product_id._get_active_flash_sale() res['has_flashsale'] = True if len(flashsales) > 0 else False diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 28794f41..49b38e6a 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -144,3 +144,4 @@ access_vit_kota,access.vit.kota,model_vit_kota,,1,1,1,1 access_v_brand_product_category,access.v.brand.product.category,model_v_brand_product_category,,1,1,1,1 access_web_find_page,access.web.find.page,model_web_find_page,,1,1,1,1 access_v_requisition_match_po,access.v.requisition.match.po,model_v_requisition_match_po,,1,1,1,1 +access_approval_retur_picking,access.approval.retur.picking,model_approval_retur_picking,,1,1,1,1 diff --git a/indoteknik_custom/views/approval_retur_picking.xml b/indoteknik_custom/views/approval_retur_picking.xml new file mode 100644 index 00000000..5ce28e20 --- /dev/null +++ b/indoteknik_custom/views/approval_retur_picking.xml @@ -0,0 +1,27 @@ +<odoo> + <!-- Form View for Stock Return Note Wizard --> + <record id="view_stock_return_note_form" model="ir.ui.view"> + <field name="name">approval.retur.picking.form</field> + <field name="model">approval.retur.picking</field> + <field name="arch" type="xml"> + <form string="Add Return Note"> + <group> + <span>Ask Approval Retur?</span> + </group> + <footer> + <button name="action_confirm_note_return" string="Confirm" type="object" class="btn-primary"/> + <button string="Cancel" class="btn-secondary" special="cancel"/> + </footer> + </form> + </field> + </record> + + <!-- Action to Open the Wizard --> + <record id="action_stock_return_note_wizard" model="ir.actions.act_window"> + <field name="name">Add Return Note</field> + <field name="res_model">approval.retur.picking</field> + <field name="view_mode">form</field> + <field name="view_id" ref="view_stock_return_note_form"/> + <field name="target">new</field> + </record> +</odoo> diff --git a/indoteknik_custom/views/requisition.xml b/indoteknik_custom/views/requisition.xml index 16373912..957113a7 100644 --- a/indoteknik_custom/views/requisition.xml +++ b/indoteknik_custom/views/requisition.xml @@ -52,10 +52,10 @@ <form> <header> <button name="button_approve" - string="Approve" - type="object" - class="mr-2 oe_highlight" - /> + string="Approve" + type="object" + class="mr-2 oe_highlight" + /> </header> <sheet string="Requisition"> <div class="oe_button_box" name="button_box"/> |
