summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2023-12-22 13:35:26 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2023-12-22 13:35:26 +0700
commit8a10587c8582ed68944634928c9a7c34d3321dbe (patch)
tree99d93c45df499d9701e2f31d995d5b7160a34a2f
parentfbb11ab07e66b28459375af175459c3a23148597 (diff)
matches so on po and matches po on so
-rwxr-xr-xindoteknik_custom/models/__init__.py2
-rw-r--r--indoteknik_custom/models/automatic_purchase.py237
-rwxr-xr-xindoteknik_custom/models/product_template.py5
-rwxr-xr-xindoteknik_custom/models/purchase_order.py1
-rwxr-xr-xindoteknik_custom/models/purchase_order_line.py10
-rw-r--r--indoteknik_custom/models/purchase_order_sales_match.py22
-rw-r--r--indoteknik_custom/models/sales_order_purchase_match.py22
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv4
-rwxr-xr-xindoteknik_custom/views/purchase_order.xml26
-rwxr-xr-xindoteknik_custom/views/sale_order.xml20
10 files changed, 292 insertions, 57 deletions
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py
index 4faf969d..fb986c0d 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -96,3 +96,5 @@ from . import commision
from . import sale_advance_payment_inv
from . import purchasing_job
from . import purchasing_job_multi_update
+from . import purchase_order_sales_match
+from . import sales_order_purchase_match
diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py
index a7b24b4f..070db78f 100644
--- a/indoteknik_custom/models/automatic_purchase.py
+++ b/indoteknik_custom/models/automatic_purchase.py
@@ -1,7 +1,7 @@
from odoo import models, api, fields
from odoo.exceptions import UserError
from datetime import datetime
-import logging
+import logging, math
_logger = logging.getLogger(__name__)
@@ -50,64 +50,195 @@ class AutomaticPurchase(models.Model):
raise UserError('Tidak ada Lines, belum bisa create PO')
if self.is_po:
raise UserError('Sudah pernah di create PO')
+
current_time = datetime.now()
- vendor_ids = self.env['automatic.purchase.line'].read_group([('automatic_purchase_id', '=', self.id), ('partner_id', '!=', False)], fields=['partner_id'], groupby=['partner_id'])
-
- counter_po_number = 0
+ vendor_ids = self.env['automatic.purchase.line'].read_group(
+ [('automatic_purchase_id', '=', self.id), ('partner_id', '!=', False)],
+ fields=['partner_id'],
+ groupby=['partner_id']
+ )
+
+ counter = 0
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,
- 'note_description': 'Automatic PO'
- }
+ self.create_po_by_vendor(vendor['partner_id'][0])
+
+ # param_header = {
+ # 'partner_id': vendor['partner_id'][0],
+ # '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,
+ # 'note_description': 'Automatic PO'
+ # }
+
+ # products_vendors = self.env['automatic.purchase.line'].search([
+ # ('automatic_purchase_id', '=', self.id),
+ # ('partner_id', '=', vendor['partner_id'][0]),
+ # ('qty_purchase', '>', 0)
+ # ], order='brand_id')
+ # counter += 1
# 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)
- ], order='brand_id')
- count = brand_id = 0
- for product in products_vendors:
- if count == 200 or brand_id != product.brand_id.id:
- count = 0
- counter_po_number += 1
- new_po = self.env['purchase.order'].create([param_header])
- new_po.name = new_po.name + "/A/"+str(counter_po_number)
- self.env['automatic.purchase.match'].create([{
- 'automatic_purchase_id': self.id,
- 'order_id': new_po.id
- }])
- self.env.cr.commit()
- # else:
- # new_po = self.env['purchase.order'].create([param_header])
- brand_id = product.brand_id.id
- count += 10
-
- qty_available = product.product_id.qty_onhand_bandengan + product.product_id.qty_incoming_bandengan - product.product_id.outgoing_qty
- suggest = 'harus beli'
- if qty_available > product.qty_purchase:
- suggest = 'masih cukup'
+ # new_po.name = new_po.name + "/A/" + str(counter)
+ # self.env['automatic.purchase.match'].create([{
+ # 'automatic_purchase_id': self.id,
+ # 'order_id': new_po.id
+ # }])
+ # self.env.cr.commit()
+
+ # count = 0
+ # for product in products_vendors:
+ # if count == 20:
+ # self.create_purchase_order_sales_match(new_po)
+
+ # if count == 20:
+ # counter += 1
+ # new_po = self.env['purchase.order'].create([param_header])
+ # new_po.name = new_po.name + "/B/" + str(counter)
+ # self.env['automatic.purchase.match'].create([{
+ # 'automatic_purchase_id': self.id,
+ # 'order_id': new_po.id
+ # }])
+
+ # self.create_purchase_order_sales_match(new_po)
+ # self.env.cr.commit()
+
+ # count += 1
+ # qty_available = (
+ # product.product_id.qty_onhand_bandengan +
+ # product.product_id.qty_incoming_bandengan -
+ # product.product_id.outgoing_qty
+ # )
+ # suggest = 'harus beli' if qty_available <= product.qty_purchase else 'masih cukup'
+ # param_line = {
+ # 'order_id': new_po.id,
+ # 'product_id': product.product_id.id,
+ # 'product_qty': product.qty_purchase,
+ # 'qty_available_store': qty_available,
+ # 'suggest': suggest,
+ # '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
+
+ # self.create_purchase_order_sales_match(new_po)
+
+ self.notification = 'PO Created successfully'
+ self.is_po = True
+
+ def create_po_by_vendor(self, vendor_id):
+ current_time = datetime.now()
+
+ PRODUCT_PER_PO = 20
+
+ auto_purchase_line = self.env['automatic.purchase.line']
+
+ param_header = {
+ 'partner_id': vendor_id,
+ '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,
+ 'note_description': 'Automatic PO'
+ }
+
+ domain = [
+ ('automatic_purchase_id', '=', self.id),
+ ('partner_id', '=', vendor_id),
+ ('qty_purchase', '>', 0)
+ ]
+
+ products_len = auto_purchase_line.search_count(domain)
+ page = math.ceil(products_len / PRODUCT_PER_PO)
+
+ # i start from zero (0)
+ for i in range(page):
+ new_po = self.env['purchase.order'].create([param_header])
+ new_po.name = new_po.name + "/A/" + str(i + 1)
+
+ self.env['automatic.purchase.match'].create([{
+ 'automatic_purchase_id': self.id,
+ 'order_id': new_po.id
+ }])
+
+ lines = auto_purchase_line.search(
+ domain,
+ offset=i * PRODUCT_PER_PO,
+ limit=PRODUCT_PER_PO
+ )
+
+ for line in lines:
+ product = line.product_id
param_line = {
'order_id': new_po.id,
- 'sequence': count,
- 'product_id': product.product_id.id,
- 'product_qty': product.qty_purchase,
- 'qty_available_store': qty_available,
- 'suggest': suggest,
- 'product_uom_qty': product.qty_purchase,
- 'price_unit': product.last_price,
+ 'product_id': product.id,
+ 'product_qty': line.qty_purchase,
+ 'qty_available_store': product.qty_available_bandengan,
+ 'suggest': product._get_po_suggest(line.qty_purchase),
+ 'product_uom_qty': line.qty_purchase,
+ 'price_unit': line.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.is_po = True
+ new_po_line = self.env['purchase.order.line'].create([param_line])
+ line.current_po_id = new_po.id
+ line.current_po_line_id = new_po_line.id
+
+ self.create_purchase_order_sales_match(new_po)
+
+
+ def create_purchase_order_sales_match(self, purchase_order):
+ matches_so_product_ids = [line.product_id.id for line in purchase_order.order_line]
+
+ matches_so = self.env['automatic.purchase.sales.match'].search([
+ ('automatic_purchase_id', '=', self.id),
+ ('sale_line_id.product_id', 'in', matches_so_product_ids),
+ ])
+
+ for sale_order in matches_so:
+ matches_so_line = {
+ 'purchase_order_id': purchase_order.id,
+ 'sale_id': sale_order.sale_id.id,
+ 'sale_line_id': sale_order.sale_line_id.id,
+ 'picking_id': sale_order.picking_id.id,
+ 'move_id': sale_order.move_id.id,
+ 'partner_id': sale_order.partner_id.id,
+ 'partner_invoice_id': sale_order.partner_invoice_id.id,
+ 'salesperson_id': sale_order.salesperson_id.id,
+ 'product_id': sale_order.product_id.id,
+ 'qty_so': sale_order.qty_so,
+ 'qty_po': sale_order.qty_po,
+ }
+ po_matches_so_line = self.env['purchase.order.sales.match'].create([matches_so_line])
+
+ self.create_sales_order_purchase_match(purchase_order)
+
+ def create_sales_order_purchase_match(self, purchase_order):
+ #TODO add matches po to sales order by automatic_purchase.sales.match
+ matches_po_product_ids = [line.product_id.id for line in purchase_order.order_line]
+
+ sales_match_line = self.env['automatic.purchase.sales.match'].search([
+ ('automatic_purchase_id', '=', self.id),
+ ('sale_line_id.product_id', 'in', matches_po_product_ids),
+ ])
+
+ for sales_match in sales_match_line:
+ purchase_line = self.env['automatic.purchase.line'].search([
+ ('automatic_purchase_id', '=', self.id),
+ ('product_id', 'in', [sales_match.product_id.id]),
+ ])
+
+ matches_po_line = {
+ 'sales_order_id' : sales_match.sale_id.id,
+ 'purchase_order_id' : purchase_line.current_po_id.id,
+ 'purchase_line_id' : purchase_line.current_po_line_id.id,
+ 'product_id' : sales_match.product_id.id,
+ 'qty_so' : sales_match.qty_so,
+ 'qty_po' : sales_match.qty_po,
+ }
+
+ sales_order_purchase_match = self.env['sales.order.purchase.match'].create([matches_po_line])
def generate_regular_purchase(self):
if self.apo_type == 'reordering':
diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py
index 34aff4fa..7ec5a002 100755
--- a/indoteknik_custom/models/product_template.py
+++ b/indoteknik_custom/models/product_template.py
@@ -347,6 +347,11 @@ class ProductProduct(models.Model):
sla_version = fields.Integer(string="SLA Version", default=0)
is_edited = fields.Boolean(string='Is Edited')
qty_sold = fields.Float(string='Sold Quantity', compute='_get_qty_sold')
+
+ def _get_po_suggest(self, qty_purchase):
+ if self.qty_available_bandengan < qty_purchase:
+ return 'harus beli'
+ return 'masih cukup'
def _get_qty_upcoming(self):
for product in self:
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py
index 285c5a95..82ca3108 100755
--- a/indoteknik_custom/models/purchase_order.py
+++ b/indoteknik_custom/models/purchase_order.py
@@ -16,6 +16,7 @@ _logger = logging.getLogger(__name__)
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
+ order_sales_match_line = fields.One2many('purchase.order.sales.match', 'purchase_order_id', string='Sales Match Lines', states={'cancel': [('readonly', True)], 'done': [('readonly', True)]}, copy=True)
sale_order_id = fields.Many2one('sale.order', string='Sale Order')
procurement_status = fields.Char(string='Procurement Status', compute='get_procurement_status', readonly=True)
po_status = fields.Selection([
diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py
index 95813e0d..8d7d818b 100755
--- a/indoteknik_custom/models/purchase_order_line.py
+++ b/indoteknik_custom/models/purchase_order_line.py
@@ -34,10 +34,16 @@ class PurchaseOrderLine(models.Model):
is_ltc = fields.Boolean(string='Sudah di LTC', default=False, help='centang ini jika barang sudah di LTC')
note = fields.Char(string='Note')
sale_automatic_id = fields.Many2one('sale.order', string='SO')
+
+
+ # so_line.qty_reserved (compute)
+ # so_line.qty_reserved = get from picking_ids where type outgoing and prodid = line.prodid
+ # po_line.qty_reserved = cek dulu apakah ada relasi ke sale order. Jika ada maka ambil sesuai yang ada di sale order (so_line.qty_reserved),
+ # jika tidak maka 0
def suggest_purchasing(self):
- for line in self:
- if line.qty_available < line.product_qty:
+ for line in self:
+ if line.product_id.qty_available_bandengan + line.qty_reserved < line.product_qty:
line.suggest = 'harus beli'
else:
line.suggest = 'masih cukup'
diff --git a/indoteknik_custom/models/purchase_order_sales_match.py b/indoteknik_custom/models/purchase_order_sales_match.py
new file mode 100644
index 00000000..02c19b1f
--- /dev/null
+++ b/indoteknik_custom/models/purchase_order_sales_match.py
@@ -0,0 +1,22 @@
+from odoo import fields, models, api, _
+from odoo.exceptions import AccessError, UserError, ValidationError
+from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class PurchaseOrderSalesMatch(models.Model):
+ _name = 'purchase.order.sales.match'
+
+ purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order', index=True, required=True, ondelete='cascade')
+ sale_id = fields.Many2one('sale.order', string='SO')
+ sale_line_id = fields.Many2one('sale.order.line', string='SO Line')
+ picking_id = fields.Many2one('stock.picking', string='Picking')
+ move_id = fields.Many2one('stock.move', string='Move')
+ partner_id = fields.Many2one('res.partner', string='Partner')
+ partner_invoice_id = fields.Many2one('res.partner', string='Invoice Partner')
+ salesperson_id = fields.Many2one('res.users', string='Sales')
+ product_id = fields.Many2one('product.product', string='Product')
+ qty_so = fields.Float(string='Qty SO')
+ qty_po = fields.Float(string='Qty PO') \ No newline at end of file
diff --git a/indoteknik_custom/models/sales_order_purchase_match.py b/indoteknik_custom/models/sales_order_purchase_match.py
new file mode 100644
index 00000000..f5436335
--- /dev/null
+++ b/indoteknik_custom/models/sales_order_purchase_match.py
@@ -0,0 +1,22 @@
+from odoo import fields, models, api, _
+from odoo.exceptions import AccessError, UserError, ValidationError
+from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class SalesOrderPurchaseMatch(models.Model):
+ _name = 'sales.order.purchase.match'
+
+ sales_order_id = fields.Many2one('sale.order', string='Sale Order', index=True, required=True, ondelete='cascade')
+ purchase_order_id = fields.Many2one('purchase.order', string='SO')
+ purchase_line_id = fields.Many2one('purchase.order.line', string='SO Line')
+ product_id = fields.Many2one('product.product', string='Product')
+ qty_so = fields.Float(string='Qty SO')
+ qty_po = fields.Float(string='Qty PO')
+ # picking_id = fields.Many2one('stock.picking', string='Picking')
+ # move_id = fields.Many2one('stock.move', string='Move')
+ # partner_id = fields.Many2one('res.partner', string='Partner')
+ # partner_invoice_id = fields.Many2one('res.partner', string='Invoice Partner')
+ # salesperson_id = fields.Many2one('res.users', string='Sales') \ No newline at end of file
diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv
index e4535561..c22ec688 100755
--- a/indoteknik_custom/security/ir.model.access.csv
+++ b/indoteknik_custom/security/ir.model.access.csv
@@ -88,4 +88,6 @@ access_v_purchasing_job,access.v.purchasing.job,model_v_purchasing_job,,1,1,1,1
access_sale_advance_payment_inv,access.sale.advance.payment.inv,model_sale_advance_payment_inv,,1,1,1,1
access_purchasing_job_multi_update,access.purchasing.job.multi.update,model_purchasing_job_multi_update,,1,1,1,1
access_automatic_purchase_sales_match,access.automatic.purchase.sales.match,model_automatic_purchase_sales_match,,1,1,1,1
-access_v_sales_outstanding,access.v.sales.outstanding,model_v_sales_outstanding,,1,1,1,1 \ No newline at end of file
+access_v_sales_outstanding,access.v.sales.outstanding,model_v_sales_outstanding,,1,1,1,1
+access_purchase_order_sales_match,access.purchase.order.sales.match,model_purchase_order_sales_match,,1,1,1,1
+access_sales_order_purchase_match,access.sale.order.purchase.match,model_sales_order_purchase_match,,1,1,1,1 \ No newline at end of file
diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml
index 8e74df4a..c118f3fb 100755
--- a/indoteknik_custom/views/purchase_order.xml
+++ b/indoteknik_custom/views/purchase_order.xml
@@ -101,6 +101,11 @@
<field name="purchase_order_lines"/>
</page>
</xpath>
+ <xpath expr="//form/sheet/notebook/page[@name='purchase_delivery_invoice']" position="after">
+ <page string="Matches SO" name="purchase_order_sales_matches_lines">
+ <field name="order_sales_match_line"/>
+ </page>
+ </xpath>
</field>
</record>
</data>
@@ -186,4 +191,25 @@
</field>
</record>
</data>
+
+ <data>
+ <record id="purchase_order_sales_matches_tree" model="ir.ui.view">
+ <field name="name">purchase.order.sales.matches.tree</field>
+ <field name="model">purchase.order.sales.match</field>
+ <field name="arch" type="xml">
+ <tree editable="top" create="false" delete="false">
+ <field name="sale_id" readonly="1"/>
+ <field name="sale_line_id" readonly="1" optional="hide"/>
+ <field name="picking_id" readonly="1" optional="hide"/>
+ <field name="move_id" readonly="1" optional="hide"/>
+ <field name="partner_id" readonly="1" optional="hide"/>
+ <field name="partner_invoice_id" readonly="1"/>
+ <field name="salesperson_id" readonly="1"/>
+ <field name="product_id" readonly="1"/>
+ <field name="qty_so" readonly="1"/>
+ <field name="qty_po" readonly="1"/>
+ </tree>
+ </field>
+ </record>
+ </data>
</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index 5db2f1e1..6b4a4ed7 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -160,8 +160,10 @@
</form>
</field>
</page>
+ <page string="Matches PO" name="page_matches_po">
+ <field name="order_sales_match_line" readonly="1"/>
+ </page>
</page>
-
</field>
</record>
</data>
@@ -212,4 +214,20 @@
<field name="code">action = records.open_form_multi_update_status()</field>
</record>
</data>
+
+ <data>
+ <record id="sales_order_purchase_matches_tree" model="ir.ui.view">
+ <field name="name">sale.order.purchase.matches.tree</field>
+ <field name="model">sales.order.purchase.match</field>
+ <field name="arch" type="xml">
+ <tree editable="top" create="false" delete="false">
+ <field name="purchase_order_id" readonly="1"/>
+ <field name="purchase_line_id" readonly="1"/>
+ <field name="product_id" readonly="1"/>
+ <field name="qty_so" readonly="1"/>
+ <field name="qty_po" readonly="1"/>
+ </tree>
+ </field>
+ </record>
+ </data>
</odoo> \ No newline at end of file