Merge lp:~jfb-tempo-consulting/unifield-server/US-6475 into lp:unifield-server

Proposed by jftempo
Status: Merged
Merged at revision: 6196
Proposed branch: lp:~jfb-tempo-consulting/unifield-server/US-6475
Merge into: lp:unifield-server
Diff against target: 440 lines (+200/-14)
10 files modified
bin/addons/account/invoice.py (+2/-1)
bin/addons/msf_profile/data/patches.xml (+4/-0)
bin/addons/msf_profile/i18n/fr_MF.po (+12/-0)
bin/addons/msf_profile/msf_profile.py (+20/-0)
bin/addons/purchase/purchase_order.py (+82/-13)
bin/addons/purchase/purchase_order_line.py (+33/-0)
bin/addons/purchase/purchase_view.xml (+18/-0)
bin/addons/purchase/purchase_workflow.py (+9/-0)
bin/addons/purchase_override/wizard/order_change_currency.py (+5/-0)
bin/addons/stock/stock.py (+15/-0)
To merge this branch: bzr merge lp:~jfb-tempo-consulting/unifield-server/US-6475
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+417055@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/addons/account/invoice.py'
2--- bin/addons/account/invoice.py 2022-01-06 14:20:38 +0000
3+++ bin/addons/account/invoice.py 2022-03-17 16:06:51 +0000
4@@ -1925,7 +1925,7 @@
5
6
7 def _check_untaxed_amount(self, cr, uid, vals, context=None):
8- if 'account_tax_id' in vals and vals['account_tax_id'] and vals['base_amount'] == 0:
9+ if 'account_tax_id' in vals and vals['account_tax_id'] and 'base_amount' in vals and vals['base_amount'] == 0:
10 raise osv.except_osv(_('Warning !'), _('The Untaxed Amount is zero. Please press the Save & Edit button before saving the %s tax.') % (vals['name']))
11 return True
12
13@@ -1978,6 +1978,7 @@
14
15 _columns = {
16 'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True),
17+ 'purchase_id': fields.many2one('purchase.order', 'PO', ondelete='cascade', select=True),
18 'name': fields.char('Tax Description', size=64, required=True),
19 'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]),
20 'base': fields.float('Base', digits_compute=dp.get_precision('Account')),
21
22=== modified file 'bin/addons/msf_profile/data/patches.xml'
23--- bin/addons/msf_profile/data/patches.xml 2022-02-16 11:35:18 +0000
24+++ bin/addons/msf_profile/data/patches.xml 2022-03-17 16:06:51 +0000
25@@ -753,5 +753,9 @@
26 <record id="us_9570_ocb_auto_sync_time" model="patch.scripts">
27 <field name="method">us_9570_ocb_auto_sync_time</field>
28 </record>
29+
30+ <record id="us_6475_set_has_tax_on_po" model="patch.scripts">
31+ <field name="method">us_6475_set_has_tax_on_po</field>
32+ </record>
33 </data>
34 </openerp>
35
36=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
37--- bin/addons/msf_profile/i18n/fr_MF.po 2022-03-02 17:30:56 +0000
38+++ bin/addons/msf_profile/i18n/fr_MF.po 2022-03-17 16:06:51 +0000
39@@ -114281,3 +114281,15 @@
40 #: field:sync.version.instance.monitor,platform:0
41 msgid "Platform"
42 msgstr "Plate-forme"
43+
44+#. module: purchase
45+#: view:purchase.order:0
46+msgid "Remove taxes on all PO lines ?"
47+msgstr "Supprimer les taxes sur toutes les lignes ?"
48+
49+#. module: purchase
50+#: view:purchase.order:0
51+msgid "Remove taxes on lines"
52+msgstr "Supprimer les taxes des lignes"
53+
54+
55
56=== modified file 'bin/addons/msf_profile/msf_profile.py'
57--- bin/addons/msf_profile/msf_profile.py 2022-02-18 10:27:42 +0000
58+++ bin/addons/msf_profile/msf_profile.py 2022-03-17 16:06:51 +0000
59@@ -56,6 +56,26 @@
60 'model': lambda *a: 'patch.scripts',
61 }
62
63+ def us_6475_set_has_tax_on_po(self, cr, uid, *a, **b):
64+ cr.execute('''
65+ update purchase_order
66+ set has_tax_at_line_level='t'
67+ where
68+ id in (
69+ select po.id
70+ from
71+ purchase_order_line pol, purchase_order po, purchase_order_taxe tax
72+ where
73+ po.state in ('draft', 'draft_p', 'validated', 'validated_p') and
74+ pol.order_id = po.id and
75+ pol.state not in ('cancel', 'cancel_r') and
76+ tax.ord_id = pol.id
77+ )
78+ ''')
79+ self.log_info(cr, uid, 'US-6475: set PO has tax on %d records' % cr.rowcount)
80+ return True
81+
82+
83 # UF24.0
84 def us_9570_ocb_auto_sync_time(self, cr, uid, *a, **b):
85 entity_obj = self.pool.get('sync.client.entity')
86
87=== modified file 'bin/addons/purchase/purchase_order.py'
88--- bin/addons/purchase/purchase_order.py 2022-02-08 11:03:36 +0000
89+++ bin/addons/purchase/purchase_order.py 2022-03-17 16:06:51 +0000
90@@ -77,23 +77,50 @@
91 def _amount_all(self, cr, uid, ids, field_name, arg, context=None):
92 res = {}
93 cur_obj = self.pool.get('res.currency')
94- for order in self.browse(cr, uid, ids, context=context):
95+ pol_obj = self.pool.get('purchase.order.line')
96+ tax_obj = self.pool.get('account.tax')
97+ for order in self.browse(cr, uid, ids, fields_to_fetch=['pricelist_id', 'partner_address_id', 'partner_id', 'tender_id'], context=context):
98 res[order.id] = {
99 'amount_untaxed': 0.0,
100 'amount_tax': 0.0,
101 'amount_total': 0.0,
102 'amount_total_tender_currency': 0.0,
103+ 'has_tax_at_line_level': False,
104 }
105- val = val1 = 0.0
106+ amount_tax = 0
107+ amount_untaxed = 0
108 cur = order.pricelist_id.currency_id
109- for line in order.order_line:
110- if line.state not in ('cancel', 'cancel_r'):
111- val1 += line.price_subtotal
112- for c in self.pool.get('account.tax').compute_all(cr, uid, line.taxes_id, line.price_unit, line.product_qty, order.partner_address_id.id, line.product_id.id, order.partner_id)['taxes']:
113- val += c.get('amount', 0.0)
114- res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur.rounding, val)
115- res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur.rounding, val1)
116+
117+ cr.execute("""select exists(
118+ select pol.id from purchase_order_line pol, purchase_order_taxe t
119+ where
120+ t.ord_id = pol.id and pol.state not in ('cancel', 'cancel_r') and pol.order_id = %s)""", (order.id, ))
121+ res[order.id]['has_tax_at_line_level'] = cr.fetchone()[0]
122+
123+ if not res[order.id]['has_tax_at_line_level']:
124+ cr.execute("select sum(price_unit * product_qty) from purchase_order_line where order_id = %s and state not in ('cancel', 'cancel_r')", (order.id, ))
125+ amount_untaxed = cr.fetchone()[0] or 0
126+
127+ cr.execute("select sum(amount) from account_invoice_tax where purchase_id = %s", (order.id, ))
128+ amount_tax = cr.fetchone()[0] or 0
129+
130+ else:
131+ cr.execute("select pol.id from purchase_order_line pol where pol.state not in ('cancel', 'cancel_r') and pol.order_id = %s", (order.id, ))
132+ pol_ids = [x[0] for x in cr.fetchall()]
133+ max_size = 400
134+ offset = 0
135+ while offset < len(pol_ids):
136+ for line in pol_obj.browse(cr, uid, pol_ids[offset:max_size+offset], fields_to_fetch=['taxes_id', 'price_unit', 'product_qty', 'product_id'], context=context):
137+ tax_data = tax_obj.compute_all(cr, uid, line.taxes_id, line.price_unit, line.product_qty, order.partner_address_id.id, line.product_id.id, order.partner_id)
138+ amount_untaxed += tax_data.get('total', 0)
139+ for c in tax_data['taxes']:
140+ amount_tax += c.get('amount', 0.0)
141+ offset += max_size
142+
143+ res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur.rounding, amount_tax)
144+ res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur.rounding, amount_untaxed)
145 res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax']
146+
147 if order.tender_id and order.tender_id.currency_id \
148 and order.tender_id.currency_id.id != order.pricelist_id.currency_id.id:
149 res[order.id]['amount_total_tender_currency'] = round(cur_obj.compute(cr, uid, cur.id, order.tender_id.currency_id.id,
150@@ -207,6 +234,12 @@
151
152 return res
153
154+ def _get_order_from_corner_tax(self, cr, uid, ids, context=None):
155+ if ids:
156+ cr.execute('select purchase_id from account_invoice_tax where id in %s', (tuple(ids),))
157+ return [x[0] for x in cr.fetchall()]
158+ return []
159+
160 def _get_order(self, cr, uid, ids, context=None):
161 result = {}
162 for line in self.pool.get('purchase.order.line').browse(cr, uid, ids, fields_to_fetch=['order_id'], context=context):
163@@ -852,6 +885,12 @@
164 'purchase.order.line': (_get_order, ['date_planned'], 10),
165 }
166 ),
167+ 'has_tax_at_line_level': fields.function(_amount_all, method=True, type='boolean', string='Tax at line', store= {
168+ 'purchase.order.line': [
169+ (_get_order, ['taxes_id'], 10),
170+ (_get_order_state_changed, ['state'], 10),
171+ ]
172+ }, multi="sums"),
173 'amount_untaxed': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Untaxed Amount',
174 store={
175 'purchase.order.line': [
176@@ -864,14 +903,21 @@
177 'purchase.order.line': [
178 (_get_order, ['price_subtotal', 'taxes_id', 'price_unit', 'product_qty', 'product_id'], 10),
179 (_get_order_state_changed, ['state'], 10),
180- ]
181+ (_get_order_from_corner_tax, ['purchase_id', 'amount'], 10),
182+ ],
183+ 'account.invoice.tax': [
184+ (_get_order_from_corner_tax, ['purchase_id', 'amount'], 10),
185+ ],
186 }, multi="sums", help="The tax amount"),
187 'amount_total': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Total',
188 store={
189 'purchase.order.line': [
190 (_get_order, ['price_subtotal', 'taxes_id', 'price_unit', 'product_qty', 'product_id'], 10),
191 (_get_order_state_changed, ['state'], 10),
192- ]
193+ ],
194+ 'account.invoice.tax': [
195+ (_get_order_from_corner_tax, ['purchase_id', 'amount'], 10),
196+ ],
197 }, multi="sums", help="The total amount"),
198 'amount_total_tender_currency': fields.function(_amount_all, method=True, string='Total (Comparison Currency)',
199 digits_compute= dp.get_precision('Purchase Price'), store=False,
200@@ -927,6 +973,7 @@
201 'not_beyond_validated': fields.function(_get_not_beyond_validated, type='boolean', string="Check if lines' and document's state is not beyond validated", method=1),
202 'po_version': fields.integer('Migration: manage old flows', help='v1: dpo reception not synced up, SI/CV generated at PO confirmation', internal=1),
203 'nb_creation_message_nr': fields.function(_get_nb_creation_message_nr, type='integer', method=1, string='Number of NR creation messages'),
204+ 'tax_line': fields.one2many('account.invoice.tax', 'purchase_id', 'Tax Lines'),
205 }
206 _defaults = {
207 'po_version': 2,
208@@ -1107,7 +1154,8 @@
209 if vals.get('pricelist_id') and partner.partner_type == 'external':
210 to_curr_id = self.pool.get('product.pricelist').browse(cr, uid, vals['pricelist_id'], fields_to_fetch=['currency_id'], context=context).currency_id.id
211
212- for order in self.browse(cr, uid, ids, fields_to_fetch=['state', 'date_order', 'partner_id', 'order_line', 'pricelist_id'], context=context):
213+ for order in self.browse(cr, uid, ids, fields_to_fetch=['state', 'date_order', 'partner_id', 'order_line', 'pricelist_id', 'tax_line'], context=context):
214+ line_changed= False
215 if order.state in ('draft', 'draft_p', 'validated') and vals['partner_id'] != order.partner_id.id:
216 for line in order.order_line:
217 if line.state in ('draft', 'validated_n', 'validated'):
218@@ -1133,8 +1181,15 @@
219 from_curr_id = order.pricelist_id.currency_id.id
220 price_to_convert = line.price_unit
221
222+ line_changed = True
223 new_price = cur_obj.compute(cr, uid, from_curr_id, to_curr_id, price_to_convert, round=False)
224 pol_obj.write(cr, uid, line.id, {'price_unit': new_price}, context=context)
225+ if line_changed:
226+ tax_line_obj = self.pool.get('account.invoice.tax')
227+ for tax_line in order.tax_line:
228+ new_price = cur_obj.compute(cr, uid, order.pricelist_id.currency_id.id, to_curr_id, tax_line.amount, round=False)
229+ tax_line_obj.write(cr, uid, tax_line.id, {'amount': new_price}, context=context)
230+
231
232 return super(purchase_order, self).write_web(cr, uid, ids, vals, context=context)
233
234@@ -1164,7 +1219,14 @@
235 if vals.get('partner_id', False):
236 partner = self.pool.get('res.partner').browse(cr, uid, vals.get('partner_id'), context=context)
237 # partner type - always set
238- vals.update({'partner_type': partner.partner_type, })
239+ vals.update({'partner_type': partner.partner_type})
240+ if partner.partner_type != 'external':
241+ vals['tax_line'] = False
242+ tax_obj = self.pool.get('account.invoice.tax')
243+ tax_lines_ids = tax_obj.search(cr, uid, [('purchase_id', 'in', ids)], context=context)
244+ if tax_lines_ids:
245+ tax_obj.unlink(cr, uid, tax_lines_ids, context=context)
246+
247 # internal type (zone) - always set
248 vals.update({'internal_type': partner.zone, })
249 # erase delivery_confirmed_date if partner_type is internal or section and the date is not filled by synchro - considered updated by synchro by default
250@@ -2750,6 +2812,13 @@
251
252 return True
253
254+ def remove_line_tax(self, cr, uid, ids, context=None):
255+ pol_obj = self.pool.get('purchase.order.line')
256+ pol_ids = pol_obj.search(cr, uid, [('order_id', 'in', ids), ('state', 'not in', ['confirmed', 'cancel', 'cancel_r', 'done']), ('taxes_id', '!=', False)], context=context)
257+ if pol_ids:
258+ pol_obj.write(cr, uid, pol_ids, {'taxes_id': [(6, 0, [])]}, context=context)
259+ return True
260+
261 # CTRL
262 def update_supplier_info(self, cr, uid, ids, context=None, *args, **kwargs):
263 '''
264
265=== modified file 'bin/addons/purchase/purchase_order_line.py'
266--- bin/addons/purchase/purchase_order_line.py 2021-12-21 09:46:40 +0000
267+++ bin/addons/purchase/purchase_order_line.py 2022-03-17 16:06:51 +0000
268@@ -28,7 +28,13 @@
269 '''
270 Return True if the system configuration VAT management is set to True
271 '''
272+
273+ if context is None:
274+ context = {}
275 vat_ok = self.pool.get('unifield.setup.configuration').get_config(cr, uid).vat_ok
276+ if vat_ok and 'purchase_id' in context:
277+ vat_ok = not self.pool.get('account.invoice.tax').search_exists(cr, uid, [('purchase_id', '=', context['purchase_id'])], context=context)
278+
279 res = {}
280 for id in ids:
281 res[id] = vat_ok
282@@ -2117,6 +2123,18 @@
283 if pol.order_id.id not in inv_ids:
284 inv_ids[pol.order_id.id] = pol.order_id.action_invoice_get_or_create(context=context)
285
286+ all_taxes = {}
287+ if pol.order_id.tax_line and pol.order_id.amount_untaxed:
288+ percent = (pol.product_qty * pol.price_unit) / pol.order_id.amount_untaxed
289+ all_taxes.setdefault(inv_ids[pol.order_id.id], {})
290+ for tax_line in pol.order_id.tax_line:
291+ key = (tax_line.account_tax_id and tax_line.account_tax_id.id or False, tax_line.account_id.id, tax_line.partner_id and tax_line.partner_id.id or False)
292+ if key not in all_taxes[inv_ids[pol.order_id.id]]:
293+ all_taxes[inv_ids[pol.order_id.id]][key] = {
294+ 'tax_line': tax_line,
295+ 'amount': 0,
296+ }
297+ all_taxes[inv_ids[pol.order_id.id]][key]['amount'] += tax_line.amount * percent
298
299 if pol.product_id:
300 account_id = pol.product_id.product_tmpl_id.property_account_expense.id
301@@ -2150,6 +2168,21 @@
302 }, context=context)
303
304 self.write(cr, uid, ids, {'invoiced': True}, context=context)
305+
306+ for inv_id in all_taxes:
307+ for key in all_taxes[inv_id]:
308+ tax_id = self.pool.get('account.invoice.tax').search(cr, uid, [('invoice_id', '=', inv_id), ('account_tax_id', '=', key[0]), ('account_id', '=', key[1]), ('partner_id', '=', key[2])], context=context)
309+ if not tax_id:
310+ self.pool.get('account.invoice.tax').create(cr, uid, {
311+ 'invoice_id': inv_id,
312+ 'account_tax_id': key[0],
313+ 'account_id': key[1],
314+ 'partner_id': key[2],
315+ 'name': all_taxes[inv_id][key]['tax_line'].name,
316+ 'amount': all_taxes[inv_id][key]['amount']}, context=context)
317+ else:
318+ cr.execute('update account_invoice_tax set amount=amount+%s where id = %s', (all_taxes[inv_id][key]['amount'], tax_id[0]))
319+
320 self.pool.get('account.invoice').button_compute(cr, uid, inv_ids.values(), {'type':'in_invoice'}, set_total=True)
321
322
323
324=== modified file 'bin/addons/purchase/purchase_view.xml'
325--- bin/addons/purchase/purchase_view.xml 2022-02-07 14:54:33 +0000
326+++ bin/addons/purchase/purchase_view.xml 2022-03-17 16:06:51 +0000
327@@ -386,6 +386,23 @@
328 <field name="currency_id"/>
329 </tree>
330 </field>
331+ <field name="has_tax_at_line_level" invisible="1" />
332+ <field name="tax_line" nolabel="1" attrs="{'invisible': [('partner_type', '!=', 'external')], 'readonly': ['|', ('not_beyond_validated','=', False), ('has_tax_at_line_level', '=', True)]}">
333+ <tree editable="bottom" string="Taxes">
334+ <field name="account_tax_id" on_change="tax_code_change(account_tax_id, parent.amount_untaxed, parent.partner_id, context)" />
335+ <field name="name"/>
336+
337+ <field name="account_id"
338+ domain="[('type', 'not in', ['view', 'consolidation']),
339+ ('user_type_code', '=', 'tax')]"/>
340+
341+ <field name="partner_id" readonly="1"/>
342+ <field name="base" readonly="1"/>
343+ <field name="amount" />
344+ <field name="base_amount" invisible="1"/>
345+ </tree>
346+ </field>
347+
348 </page>
349 <page string="Notes">
350 <group colspan="4" col="6">
351@@ -430,6 +447,7 @@
352 <field name="functional_amount_untaxed"/>
353 <field name="functional_amount_tax"/>
354 <field name="functional_amount_total"/>
355+ <button type="object" string="Remove taxes on lines" name="remove_line_tax" attrs="{'invisible': ['|', ('has_tax_at_line_level', '=', False), ('not_beyond_validated', '=', False)]}" icon="gtk-cut" confirm="Remove taxes on all PO lines ?"/>
356 <newline/>
357 <field name="total_price_include_transport" readonly="1" attrs="{'invisible': ['|', ('categ', '=', 'transport'), ('display_intl_transport_ok', '=', False)]}"/>
358 <newline/>
359
360=== modified file 'bin/addons/purchase/purchase_workflow.py'
361--- bin/addons/purchase/purchase_workflow.py 2021-10-04 14:56:23 +0000
362+++ bin/addons/purchase/purchase_workflow.py 2022-03-17 16:06:51 +0000
363@@ -879,6 +879,13 @@
364 self.generate_invoice(cr, uid, pol_to_invoice.keys(), context=context)
365 return True
366
367+ def update_tax_corner(self, cr, uid, ids, context=None):
368+ for pol in self.browse(cr, uid, ids, fields_to_fetch=['product_qty', 'price_unit', 'order_id'], context=context):
369+ if pol.order_id.tax_line and pol.order_id.amount_untaxed:
370+ percent = (pol.product_qty * pol.price_unit) / pol.order_id.amount_untaxed
371+ for tax_line in pol.order_id.tax_line:
372+ self.pool.get('account.invoice.tax').write(cr, uid, tax_line.id, {'amount': round(tax_line.amount * (1 - percent), 2)}, context=context)
373+ return True
374
375 def action_cancel(self, cr, uid, ids, context=None):
376 '''
377@@ -900,6 +907,7 @@
378 if pol.cancelled_by_sync:
379 sol_obj.write(cr, uid, pol.linked_sol_id.id, {'cancelled_by_sync': True}, context=context)
380 wf_service.trg_validate(uid, 'sale.order.line', pol.linked_sol_id.id, 'cancel', cr)
381+ self.update_tax_corner(cr, uid, ids, context=context)
382 self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
383
384 return True
385@@ -925,6 +933,7 @@
386 sol_obj.write(cr, uid, pol.linked_sol_id.id, {'cancelled_by_sync': True, 'product_uom_qty': pol.product_qty ,'product_uos_qty': pol.product_qty}, context=context)
387 wf_service.trg_validate(uid, 'sale.order.line', pol.linked_sol_id.id, 'cancel_r', cr)
388
389+ self.update_tax_corner(cr, uid, ids, context=context)
390 self.write(cr, uid, ids, {'state': 'cancel_r'}, context=context)
391
392 return True
393
394=== modified file 'bin/addons/purchase_override/wizard/order_change_currency.py'
395--- bin/addons/purchase_override/wizard/order_change_currency.py 2020-08-25 07:39:26 +0000
396+++ bin/addons/purchase_override/wizard/order_change_currency.py 2022-03-17 16:06:51 +0000
397@@ -78,12 +78,17 @@
398 currency_obj = self.pool.get('res.currency')
399 line_obj = self.pool.get('purchase.order.line')
400 order_obj = self.pool.get('purchase.order')
401+ tax_line_obj = self.pool.get('account.invoice.tax')
402
403 for wiz in self.browse(cr, uid, ids, context=context):
404 for line in wiz.order_id.order_line:
405 new_price = currency_obj.compute(cr, uid, wiz.old_pricelist_id.currency_id.id, wiz.new_pricelist_id.currency_id.id, line.price_unit, round=False, context=context)
406 line_obj.write(cr, uid, line.id, {'price_unit': new_price}, context=c)
407
408+ for tax_line in wiz.order_id.tax_line:
409+ new_price = currency_obj.compute(cr, uid, wiz.old_pricelist_id.currency_id.id, wiz.new_pricelist_id.currency_id.id, tax_line.amount, round=False, context=context)
410+ tax_line_obj.write(cr, uid, tax_line.id, {'amount': new_price}, context=c)
411+
412 order_data = {'pricelist_id': wiz.new_pricelist_id.id,}
413 # Set at least, the functional currency
414 currency_ids = [self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id]
415
416=== modified file 'bin/addons/stock/stock.py'
417--- bin/addons/stock/stock.py 2022-02-11 14:31:07 +0000
418+++ bin/addons/stock/stock.py 2022-03-17 16:06:51 +0000
419@@ -1853,6 +1853,21 @@
420 for move_line in picking.move_lines:
421 self.action_invoice_create_line(cr, uid, picking, move_line, invoice_id, group, inv_type, partner, context)
422
423+ if picking.purchase_id and picking.purchase_id.tax_line:
424+ total_po = picking.purchase_id.amount_untaxed
425+ total_invoice = invoice_obj.browse(cr, uid, [invoice_id], fields_to_fetch=['amount_untaxed'], context=context)[0].amount_untaxed
426+ if total_po and total_invoice:
427+ for tax_line in move_line.purchase_line_id.order_id.tax_line:
428+ self.pool.get('account.invoice.tax').create(cr, uid, {
429+ 'invoice_id': invoice_id,
430+ 'account_tax_id': tax_line.account_tax_id.id,
431+ 'account_id': tax_line.account_id.id,
432+ 'partner_id': tax_line.partner_id.id,
433+ 'name': tax_line.name,
434+ 'base_amount': total_invoice,
435+ 'amount': tax_line.amount * total_invoice / total_po}, context=context)
436+
437+
438 invoice_obj.button_compute(cr, uid, [invoice_id], context=context,
439 set_total=(inv_type in ('in_invoice', 'in_refund')))
440 self.write(cr, uid, [picking.id], {

Subscribers

People subscribed via source and target branches