summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIT Fixcomart <it@fixcomart.co.id>2023-03-30 01:43:11 +0000
committerIT Fixcomart <it@fixcomart.co.id>2023-03-30 01:43:11 +0000
commitb5a9a4d37c07c32fb60753f29e7d982be221999b (patch)
tree98668c355f6f5e832f368a1d0a373d7cae85b49d
parent60d0b36cf33785c0cf6bea1d10b344dcdb37695a (diff)
parent20eebfe836dcd6e971ccd0676b6294a2f3b06e5a (diff)
Merged in release (pull request #29)
Release
-rwxr-xr-xindoteknik_custom/__manifest__.py1
-rwxr-xr-xindoteknik_custom/models/__init__.py2
-rw-r--r--indoteknik_custom/models/apache_solr.py70
-rw-r--r--indoteknik_custom/models/automatic_purchase.py149
-rw-r--r--indoteknik_custom/models/invoice_reklas.py21
-rw-r--r--indoteknik_custom/models/stock_move.py33
-rw-r--r--indoteknik_custom/models/stock_picking.py12
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv6
-rw-r--r--indoteknik_custom/views/automatic_purchase.xml103
9 files changed, 384 insertions, 13 deletions
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py
index 84a604d8..5873d73a 100755
--- a/indoteknik_custom/__manifest__.py
+++ b/indoteknik_custom/__manifest__.py
@@ -68,6 +68,7 @@
'views/ip_lookup.xml',
'views/wati.xml',
'views/midtrans.xml',
+ 'views/automatic_purchase.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 7a4e445a..679004d1 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -56,3 +56,5 @@ from . import wati_api
from . import wati_contact
from . import uangmuka_penjualan
from . import uangmuka_pembelian
+from . import automatic_purchase
+from . import apache_solr
diff --git a/indoteknik_custom/models/apache_solr.py b/indoteknik_custom/models/apache_solr.py
new file mode 100644
index 00000000..16cf5908
--- /dev/null
+++ b/indoteknik_custom/models/apache_solr.py
@@ -0,0 +1,70 @@
+from odoo import models, api, fields
+from odoo.exceptions import UserError
+from datetime import datetime
+import logging
+import pysolr
+
+_logger = logging.getLogger(__name__)
+
+
+class ApacheSolr(models.Model):
+ _name = 'apache.solr'
+ _order = 'id desc'
+
+ def _sync_product_to_solr(self):
+ _logger.info('run sync to solr...')
+ solr = pysolr.Solr('http://10.148.0.5:8983/solr/product/', timeout=100)
+
+ templates = self.env['product.template'].search([
+ ('solr_flag', '=', 0),
+ # ('id', '=', 21560)
+ ], limit=500)
+ document = []
+ counter = 0
+ for template in templates:
+ counter += 1
+ price_excl_after_disc = price_excl = 0
+ variants_name = variants_code = ''
+ if template.product_variant_count > 1:
+ for variant in template.product_variant_ids:
+ if price_excl_after_disc == 0:
+ price_excl = variant._get_website_price_exclude_tax()
+ price_excl_after_disc = variant._get_website_price_after_disc_and_tax()
+ elif variant._get_website_price_after_disc_and_tax() < price_excl_after_disc:
+ price_excl_after_disc = variant._get_website_price_after_disc_and_tax()
+ price_excl = variant._get_website_price_exclude_tax()
+ else:
+ price_excl_after_disc = price_excl_after_disc
+ price_excl = price_excl
+ variants_name += variant.display_name+', '
+ variants_code += variant.default_code+', '
+
+ document=[({
+ 'id': template.id,
+ 'display_name_s': template.display_name,
+ 'name_s': template.name,
+ 'default_code_s': template.default_code,
+ 'product_rating_i': template.product_rating,
+ 'product_id_i': template.id,
+ 'image_s': self.env['ir.attachment'].api_image('product.template', 'image_512', template.id),
+ 'price_f': price_excl or template.product_variant_id._get_website_price_exclude_tax(),
+ 'price_discount_f': price_excl_after_disc or template.product_variant_id._get_website_price_after_disc_and_tax(),
+ 'tax_f': template.product_variant_id._get_website_tax(),
+ 'variant_total_i': template.product_variant_count,
+ 'stock_total_i': template.qty_stock_vendor,
+ 'weight_f': template.weight,
+ 'manufacture_id_i': template.x_manufacture.id or 0,
+ '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),
+ 'category_id_i': template.categ_id.id or 0,
+ 'category_name_s': template.categ_id.name,
+ 'variants_name_t': variants_name,
+ 'variants_code_t': variants_code,
+ 'search_rank_i': template.search_rank,
+ 'search_rank_weekly_i': template.search_rank_weekly,
+ 'active_b': template.active
+ })]
+ solr.add(document)
+ # add counter for monitoring
+ _logger.info('%s / 500' % counter)
+ _logger.info('Success add to solr product %s' % template.id)
diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py
new file mode 100644
index 00000000..e28f71f5
--- /dev/null
+++ b/indoteknik_custom/models/automatic_purchase.py
@@ -0,0 +1,149 @@
+from odoo import models, api, fields
+from odoo.exceptions import UserError
+from datetime import datetime
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class AutomaticPurchase(models.Model):
+ _name = 'automatic.purchase'
+ _order = 'id desc'
+
+ date_doc = fields.Date(string='Date', required=True, help='Isi tanggal hari ini')
+ description = fields.Char(string='Description', help='bebas isi nya apa')
+ purchase_lines = fields.One2many('automatic.purchase.line', 'automatic_purchase_id', string='Lines', auto_join=True)
+ notification = fields.Char(string='Notification')
+ is_po = fields.Boolean(string='Is PO')
+ purchase_match = fields.One2many('automatic.purchase.match', 'automatic_purchase_id', string='Matches', auto_join=True)
+ vendor_id = fields.Many2one('res.partner', string='Vendor', help='boleh kosong, jika diisi, maka hanya keluar data untuk vendor tersebut')
+
+ def create_po_from_automatic_purchase(self):
+ if not self.purchase_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['automatic.purchase.line'].read_group([('automatic_purchase_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id'])
+
+ for vendor in vendor_ids:
+ param_header = {
+ 'partner_id': vendor['partner_id'][0],
+ 'partner_ref': 'Automatic PO',
+ '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
+ }
+ new_po = self.env['purchase.order'].create([param_header])
+ products_vendors = self.env['automatic.purchase.line'].search([
+ ('automatic_purchase_id', '=', self.id),
+ ('partner_id', '=', vendor['partner_id'][0]),
+ ('qty_purchase', '>', 0)
+ ])
+ count=0
+ for product in products_vendors:
+ count += 10
+ param_line = {
+ 'order_id': new_po.id,
+ 'sequence': count,
+ 'product_id': product.product_id.id,
+ 'product_qty': product.qty_purchase,
+ 'product_uom_qty': product.qty_purchase,
+ 'price_unit': product.last_price,
+ }
+ new_line = self.env['purchase.order.line'].create([param_line])
+ product.current_po_id = new_po.id
+ product.current_po_line_id = new_line.id
+ _logger.info('Automatic Create PO Line %s' % product.product_id.name)
+ self.notification = self.notification + ' %s' % new_po.name
+ self.env['automatic.purchase.match'].create([{
+ 'automatic_purchase_id': self.id,
+ 'order_id': new_po.id
+ }])
+ self.is_po = True
+
+ def generate_automatic_purchase(self):
+ if self.purchase_lines:
+ raise UserError('Sudah digenerate sebelumnya, hapus line terlebih dahulu')
+
+ query = [
+ ('product_min_qty', '>', 0)
+ ]
+ orderpoints = self.env['stock.warehouse.orderpoint'].search(query)
+ count = 0
+ for point in orderpoints:
+ # _logger.info('test %s' % point.product_id.name)
+ if point.product_id.qty_available > point.product_min_qty:
+ continue
+ qty_purchase = point.product_max_qty - point.product_id.qty_available
+ po_line = self.env['purchase.order.line'].search([('product_id', '=', point.product_id.id), ('order_id.state', '=', 'done')], limit=1)
+
+ if self.vendor_id:
+ purchase_price = self.env['purchase.pricelist'].search([
+ ('product_id', '=', point.product_id.id),
+ ('vendor_id', '=', self.vendor_id.id)
+ ], order='product_price asc', limit=1)
+ else:
+ purchase_price = self.env['purchase.pricelist'].search([('product_id', '=', point.product_id.id)], order='product_price asc', limit=1)
+
+ vendor_id = purchase_price.vendor_id.id
+ price = purchase_price.product_price or 0
+
+ self.env['automatic.purchase.line'].create([{
+ 'automatic_purchase_id': self.id,
+ 'product_id': point.product_id.id,
+ 'qty_purchase': qty_purchase,
+ 'qty_min': point.product_min_qty,
+ 'qty_max': point.product_max_qty,
+ 'qty_available': point.product_id.qty_available,
+ # 'partner_id': po_line.order_id.partner_id.id,
+ # 'last_price': po_line.price_unit,
+ 'partner_id': vendor_id,
+ 'last_price': price,
+ 'subtotal': qty_purchase * price,
+ 'last_order_id': po_line.order_id.id,
+ 'last_orderline_id': po_line.id,
+ 'brand_id': point.product_id.product_tmpl_id.x_manufacture.id
+ }])
+ count += 1
+ _logger.info('Create Automatic Purchase Line %s' % point.product_id.name)
+ self.notification = "Automatic PO Created %s Lines" % count
+
+
+class AutomaticPurchaseLine(models.Model):
+ _name = 'automatic.purchase.line'
+ _description = 'Automatic Purchase Line'
+ _order = 'automatic_purchase_id, id'
+
+ automatic_purchase_id = fields.Many2one('automatic.purchase', string='Ref', required=True, ondelete='cascade', index=True, copy=False)
+ product_id = fields.Many2one('product.product', string='Product')
+ qty_purchase = fields.Float(string='Qty Purchase')
+ qty_min = fields.Float(string='Qty Min')
+ qty_max = fields.Float(string='Qty Max')
+ qty_available = fields.Float(string='Qty Available')
+ partner_id = fields.Many2one('res.partner', string='Vendor')
+ last_price = fields.Float(string='Last Price')
+ subtotal = fields.Float(string='Subtotal')
+ last_order_id = fields.Many2one('purchase.order', string='Last Order')
+ last_orderline_id = fields.Many2one('purchase.order.line', string='Last Order Line')
+ is_po = fields.Boolean(String='Is PO')
+ 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')
+
+
+class AutomaticPurchaseMatch(models.Model):
+ _name = 'automatic.purchase.match'
+ _order = 'automatic_purchase_id, id'
+
+ automatic_purchase_id = fields.Many2one('automatic.purchase', string='Ref', required=True, ondelete='cascade', index=True, copy=False)
+ order_id = fields.Many2one('purchase.order', string='Purchase Order')
+ vendor = fields.Char(string='Vendor', compute='_compute_info_po')
+ total = fields.Float(string='Total', compute='_compute_info_po')
+
+ def _compute_info_po(self):
+ for match in self:
+ match.vendor = match.order_id.partner_id.name
+ match.total = match.order_id.amount_total
diff --git a/indoteknik_custom/models/invoice_reklas.py b/indoteknik_custom/models/invoice_reklas.py
index 70469b72..c2ee7e3d 100644
--- a/indoteknik_custom/models/invoice_reklas.py
+++ b/indoteknik_custom/models/invoice_reklas.py
@@ -26,16 +26,19 @@ class InvoiceReklas(models.TransientModel):
invoices = self.env['account.move'].browse(self._context.get('active_ids', []))
current_time = datetime.now()
for invoice in invoices:
-
+ if self.reklas_type == 'penjualan':
+ ref_name = 'REKLAS '+self.reklas_id.name+" UANG MUKA PENJUALAN "+invoice.name+" "+invoice.partner_id.name
+ else:
+ ref_name = 'REKLAS '+self.reklas_id.name+" UANG MUKA PEMBELIAN "+invoice.name+" "+invoice.partner_id.name
if self.reklas_type == 'penjualan':
parameters_header = {
- 'ref': 'REKLAS '+self.reklas_id.name+" UANG MUKA PENJUALAN "+invoice.name+" "+invoice.partner_id.name,
+ 'ref': ref_name,
'date': current_time,
'journal_id': 13
}
else:
parameters_header = {
- 'ref': 'REKLAS ' + self.reklas_id.name + " UANG MUKA PEMBELIAN " + invoice.name + " " + invoice.partner_id.name,
+ 'ref': ref_name,
'date': current_time,
'journal_id': 13
}
@@ -50,7 +53,8 @@ class InvoiceReklas(models.TransientModel):
'partner_id': invoice.partner_id.id,
'currency_id': 12,
'debit': self.pay_amt,
- 'credit': 0
+ 'credit': 0,
+ 'name': ref_name
}
parameter_credit = {
'move_id': account_move.id,
@@ -58,7 +62,8 @@ class InvoiceReklas(models.TransientModel):
'partner_id': invoice.partner_id.id,
'currency_id': 12,
'debit': 0,
- 'credit': self.pay_amt
+ 'credit': self.pay_amt,
+ 'name': ref_name
}
else:
parameter_debit = {
@@ -67,7 +72,8 @@ class InvoiceReklas(models.TransientModel):
'partner_id': invoice.partner_id.id,
'currency_id': 12,
'debit': self.pay_amt,
- 'credit': 0
+ 'credit': 0,
+ 'name': ref_name
}
parameter_credit = {
'move_id': account_move.id,
@@ -75,7 +81,8 @@ class InvoiceReklas(models.TransientModel):
'partner_id': invoice.partner_id.id,
'currency_id': 12,
'debit': 0,
- 'credit': self.pay_amt
+ 'credit': self.pay_amt,
+ 'name': ref_name
}
request.env['account.move.line'].create([parameter_debit, parameter_credit])
return {
diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py
index 22a73010..bdbb0227 100644
--- a/indoteknik_custom/models/stock_move.py
+++ b/indoteknik_custom/models/stock_move.py
@@ -6,6 +6,39 @@ class StockMove(models.Model):
line_no = fields.Integer('No', default=0)
+ def _prepare_account_move_line_from_mr(self, po_line, qty, move=False):
+ po_line.ensure_one()
+ aml_currency = move and move.currency_id or po_line.currency_id
+ date = move and move.date or fields.Date.today()
+ res = {
+ 'display_type': po_line.display_type,
+ 'sequence': po_line.sequence,
+ 'name': '%s: %s' % (po_line.order_id.name, po_line.name),
+ 'product_id': po_line.product_id.id,
+ 'product_uom_id': po_line.product_uom.id,
+ 'quantity': qty,
+ 'price_unit': po_line.currency_id._convert(po_line.price_unit, aml_currency, po_line.company_id, date, round=False),
+ 'tax_ids': [(6, 0, po_line.taxes_id.ids)],
+ 'analytic_account_id': po_line.account_analytic_id.id,
+ 'analytic_tag_ids': [(6, 0, po_line.analytic_tag_ids.ids)],
+ 'purchase_line_id': po_line.id,
+ }
+ if not move:
+ return res
+
+ if self.currency_id == move.company_id.currency_id:
+ currency = False
+ else:
+ currency = move.currency_id
+
+ res.update({
+ 'move_id': move.id,
+ 'currency_id': currency and currency.id or False,
+ 'date_maturity': move.invoice_date_due,
+ 'partner_id': move.partner_id.id,
+ })
+ return res
+
def _create_account_move_line(self, credit_account_id, debit_account_id, journal_id, qty, description, svl_id, cost):
self.ensure_one()
if self.picking_id.is_internal_use:
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index 77af676c..e63370f5 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -84,15 +84,17 @@ class StockPicking(models.Model):
# Invoice values.
invoice_vals = order._prepare_invoice()
# Invoice line values (keep only necessary sections).
- for line in order.order_line:
- if line.display_type == 'line_section':
+ for line in self.move_ids_without_package:
+ po_line = self.env['purchase.order.line'].search([('order_id', '=', po.id), ('product_id', '=', line.product_id.id)], limit=1)
+ qty = line.product_uom_qty
+ if po_line.display_type == 'line_section':
pending_section = line
continue
- if not float_is_zero(line.qty_to_invoice, precision_digits=precision):
+ if not float_is_zero(po_line.qty_to_invoice, precision_digits=precision):
if pending_section:
- invoice_vals['invoice_line_ids'].append((0, 0, pending_section._prepare_account_move_line()))
+ invoice_vals['invoice_line_ids'].append((0, 0, pending_section._prepare_account_move_line_from_mr(po_line, qty)))
pending_section = None
- invoice_vals['invoice_line_ids'].append((0, 0, line._prepare_account_move_line()))
+ invoice_vals['invoice_line_ids'].append((0, 0, line._prepare_account_move_line_from_mr(po_line, qty)))
invoice_vals_list.append(invoice_vals)
if not invoice_vals_list:
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index 65ab0a6c..1788c77f 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -40,4 +40,8 @@ access_wati_contact,access.wati.contact,model_wati_contact,,1,1,1,1
access_user_company_request,access.user.company.request,model_user_company_request,,1,1,1,1
access_res_partner_company_type,access.res.partner.company_type,model_res_partner_company_type,,1,1,1,1
access_uangmuka_penjualan,access.uangmuka.penjualan,model_uangmuka_penjualan,,1,1,1,1
-access_uangmuka_pembelian,access.uangmuka.pembelian,model_uangmuka_pembelian,,1,1,1,1 \ No newline at end of file
+access_uangmuka_pembelian,access.uangmuka.pembelian,model_uangmuka_pembelian,,1,1,1,1
+access_automatic_purchase,access.automatic.purchase,model_automatic_purchase,,1,1,1,1
+access_automatic_purchase_line,access.automatic.purchase.line,model_automatic_purchase_line,,1,1,1,1
+access_automatic_purchase_match,access.automatic.purchase.match,model_automatic_purchase_match,,1,1,1,1
+access_apache_solr,access.apache.solr,model_apache_solr,,1,1,1,1 \ No newline at end of file
diff --git a/indoteknik_custom/views/automatic_purchase.xml b/indoteknik_custom/views/automatic_purchase.xml
new file mode 100644
index 00000000..49751f4e
--- /dev/null
+++ b/indoteknik_custom/views/automatic_purchase.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+ <record id="automatic_purchase_tree" model="ir.ui.view">
+ <field name="name">automatic.purchase.tree</field>
+ <field name="model">automatic.purchase</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="date_doc"/>
+ <field name="vendor_id"/>
+ <field name="description"/>
+ <field name="notification" readonly="1"/>
+ <field name="is_po" readonly="1"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="automatic_purchase_line_tree" model="ir.ui.view">
+ <field name="name">automatic.purchase.line.tree</field>
+ <field name="model">automatic.purchase.line</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="brand_id"/>
+ <field name="product_id"/>
+ <field name="qty_purchase"/>
+ <field name="qty_min"/>
+ <field name="qty_max"/>
+ <field name="qty_available"/>
+ <field name="partner_id"/>
+ <field name="last_price"/>
+ <field name="subtotal"/>
+ <field name="last_order_id" readonly="1"/>
+ <field name="current_po_line_id" readonly="1"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="automatic_purchase_match_tree" model="ir.ui.view">
+ <field name="name">automatic.purchase.match.tree</field>
+ <field name="model">automatic.purchase.match</field>
+ <field name="arch" type="xml">
+ <tree>
+ <field name="order_id" readonly="1"/>
+ <field name="vendor" readonly="1"/>
+ <field name="total" readonly="1"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="automatic_purchase_form" model="ir.ui.view">
+ <field name="name">automatic.purchase.form</field>
+ <field name="model">automatic.purchase</field>
+ <field name="arch" type="xml">
+ <form>
+ <sheet string="Purchase">
+ <div class="oe_button_box" name="button_box"/>
+ <group>
+ <group>
+ <field name="date_doc"/>
+ <field name="vendor_id"/>
+ <field name="description"/>
+ <field name="notification" readonly="1"/>
+ </group>
+ <group>
+ <div>
+ <button name="generate_automatic_purchase"
+ string="Generate Line"
+ type="object"
+ class="mr-2 oe_highlight"
+ />
+ <button name="create_po_from_automatic_purchase"
+ string="Create PO"
+ type="object"
+ class="mr-2 oe_highlight"
+ />
+ </div>
+ </group>
+ </group>
+ <notebook>
+ <page string="Lines">
+ <field name="purchase_lines"/>
+ </page>
+ <page string="Matches">
+ <field name="purchase_match"/>
+ </page>
+ </notebook>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="automatic_purchase_action" model="ir.actions.act_window">
+ <field name="name">Automatic Purchase</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">automatic.purchase</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <menuitem id="menu_automatic_purchase"
+ name="Automatic Purchase"
+ action="automatic_purchase_action"
+ parent="menu_monitoring_in_purchase"
+ sequence="200"/>
+</odoo> \ No newline at end of file