1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
from odoo import models, fields, tools
from odoo.exceptions import AccessError, UserError, ValidationError
from datetime import timedelta, date
class PurchasingJob(models.Model):
_name = 'purchasing.job'
_description = 'Procurement Monitoring by Product'
_auto = False
_rec_name = 'product_id'
id = fields.Integer(string='ID', readonly=True)
item_code = fields.Char(string='Item Code')
onhand = fields.Float(string='On Hand')
incoming = fields.Float(string='Incoming')
outgoing = fields.Float(string='Outgoing')
action = fields.Char(string='Action')
product_id = fields.Many2one('product.product', string='Product')
vendor_id = fields.Many2one('res.partner', string='Vendor')
brand_id = fields.Many2one('brands', string='Brand')
note = fields.Text(string='Note', compute='_compute_note')
def action_open_note_wizard(self):
self.ensure_one()
return {
'name': 'Add/Edit Note',
'type': 'ir.actions.act_window',
'res_model': 'purchasing.job.note.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'default_product_id': self.product_id.id,
'default_note': self.note,
}
}
def _compute_note(self):
for rec in self:
note_obj = self.env['purchasing.job.note'].search([
('product_id', '=', rec.product_id.id)
], limit=1)
rec.note = note_obj.note if note_obj else ''
def create_automatic_purchase(self):
if not self:
raise UserError("No Purchasing Job selected.")
automatic_purchase = self.env['automatic.purchase'].create({
'apo_type': 'purchasing_job',
})
lines_to_create = []
for stock in self:
manage_stock = self.env['manage.stock'].search([
('product_id', '=', stock.product_id.id)
], limit=1)
qty_purchase = stock.outgoing - (stock.onhand + stock.incoming)
qty_purchase = max(qty_purchase, 0.0)
pricelist = self.env['product.supplierinfo'].search([
('product_tmpl_id', '=', stock.product_id.product_tmpl_id.id),
('name', '=', stock.vendor_id.id)
], limit=1)
price = pricelist.price if pricelist else 0.0
subtotal = qty_purchase * price
lines_to_create.append({
'automatic_purchase_id': automatic_purchase.id,
'product_id': stock.product_id.id,
'qty_purchase': qty_purchase,
'qty_min': manage_stock.min_stock,
'qty_buffer': manage_stock.buffer_stock,
'partner_id': stock.vendor_id.id,
'taxes_id': stock.vendor_id.tax_id.id if stock.vendor_id.tax_id else False,
'price': price,
'brand_id': stock.brand_id.id,
'product_public_category_id': stock.product_id.product_public_category_id.id,
})
self.env['automatic.purchase.line'].create(lines_to_create)
return {
'type': 'ir.actions.act_window',
'res_model': 'automatic.purchase',
'view_mode': 'form',
'res_id': automatic_purchase.id,
'target': 'current',
}
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""
CREATE OR REPLACE VIEW %s
AS SELECT
row_number() OVER ()::integer AS id,
pmp.item_code,
max(pmp.onhand) AS onhand,
max(pmp.incoming) AS incoming,
max(pmp.outgoing) AS outgoing,
pmp.action,
pmp.product_id,
pmp.brand_id,
pmp.name as vendor_id
FROM v_procurement_monitoring_by_product_v2 pmp
WHERE pmp.action = 'kurang'::text
GROUP BY pmp.product_id, pmp.item_code, pmp.action, pmp.brand_id, pmp.name;
""" % self._table)
# def init(self):
# tools.drop_view_if_exists(self.env.cr, self._table)
# self.env.cr.execute("""
# CREATE OR REPLACE VIEW %s AS
# SELECT * FROM (
# SELECT
# row_number() OVER () AS id,
# a.item_code,
# a.product,
# a.onhand,
# a.incoming,
# a.outgoing,
# CASE
# WHEN (a.incoming + a.onhand) < a.outgoing THEN 'kurang'
# ELSE 'cukup'
# END AS action,
# a.product_id,
# pp2.vendor_id,
# b.id AS brand_id
# FROM (
# SELECT
# COALESCE(pp.default_code, pt.default_code) AS item_code,
# pt.name AS product,
# get_qty_onhand(pp.id::numeric) AS onhand,
# get_qty_incoming(pp.id::numeric) AS incoming,
# get_qty_outgoing(pp.id::numeric) AS outgoing,
# pp.id AS product_id,
# pp.brand_id
# FROM stock_move sm
# JOIN stock_picking sp ON sp.id = sm.picking_id
# JOIN product_product pp ON pp.id = sm.product_id
# JOIN product_template pt ON pt.id = pp.product_tmpl_id
# WHERE sp.state IN ('draft', 'waiting', 'confirmed', 'assigned')
# AND sp.name LIKE '%%OUT%%'
# AND sm.location_id = 55
# GROUP BY pp.id, pp.default_code, pt.default_code, pt.name, pp.brand_id
# ) a
# LEFT JOIN brands b ON b.id = a.brand_id
# LEFT JOIN LATERAL (
# SELECT vendor_id
# FROM purchase_pricelist
# WHERE product_id = a.product_id
# ORDER BY id ASC
# LIMIT 1
# ) pp2 ON true
# ) final
# WHERE final.action = 'kurang'
# """ % self._table)
# super(PurchasingJob, self).init()
class PurchasingJobNote(models.Model):
_name = 'purchasing.job.note'
_description = 'Note for Product in Purchasing Job'
product_id = fields.Many2one('product.product', string='Product', required=True, ondelete='cascade', index=True)
note = fields.Text(string='Note')
user_id = fields.Many2one('res.users', string='Created by', default=lambda self: self.env.user)
class PurchasingJobNoteWizard(models.TransientModel):
_name = 'purchasing.job.note.wizard'
_description = 'Add/Edit Note for Product'
product_id = fields.Many2one('product.product', string='Product', required=True)
note = fields.Text(string='Note')
def action_confirm(self):
self.ensure_one()
existing = self.env['purchasing.job.note'].search([
('product_id', '=', self.product_id.id)
], limit=1)
if existing:
existing.note = self.note
else:
self.env['purchasing.job.note'].create({
'product_id': self.product_id.id,
'note': self.note,
})
return {'type': 'ir.actions.act_window_close'}
|