Merge lp:~jfb-tempo-consulting/unifield-server/US-6475 into lp:unifield-server
- US-6475
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+417055@code.launchpad.net |
Commit message
Description of the change
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 | 1925 | 1925 | ||
6 | 1926 | 1926 | ||
7 | 1927 | def _check_untaxed_amount(self, cr, uid, vals, context=None): | 1927 | def _check_untaxed_amount(self, cr, uid, vals, context=None): |
9 | 1928 | if 'account_tax_id' in vals and vals['account_tax_id'] and vals['base_amount'] == 0: | 1928 | if 'account_tax_id' in vals and vals['account_tax_id'] and 'base_amount' in vals and vals['base_amount'] == 0: |
10 | 1929 | raise osv.except_osv(_('Warning !'), _('The Untaxed Amount is zero. Please press the Save & Edit button before saving the %s tax.') % (vals['name'])) | 1929 | raise osv.except_osv(_('Warning !'), _('The Untaxed Amount is zero. Please press the Save & Edit button before saving the %s tax.') % (vals['name'])) |
11 | 1930 | return True | 1930 | return True |
12 | 1931 | 1931 | ||
13 | @@ -1978,6 +1978,7 @@ | |||
14 | 1978 | 1978 | ||
15 | 1979 | _columns = { | 1979 | _columns = { |
16 | 1980 | 'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True), | 1980 | 'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True), |
17 | 1981 | 'purchase_id': fields.many2one('purchase.order', 'PO', ondelete='cascade', select=True), | ||
18 | 1981 | 'name': fields.char('Tax Description', size=64, required=True), | 1982 | 'name': fields.char('Tax Description', size=64, required=True), |
19 | 1982 | 'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]), | 1983 | 'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]), |
20 | 1983 | 'base': fields.float('Base', digits_compute=dp.get_precision('Account')), | 1984 | 'base': fields.float('Base', digits_compute=dp.get_precision('Account')), |
21 | 1984 | 1985 | ||
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 | 753 | <record id="us_9570_ocb_auto_sync_time" model="patch.scripts"> | 753 | <record id="us_9570_ocb_auto_sync_time" model="patch.scripts"> |
27 | 754 | <field name="method">us_9570_ocb_auto_sync_time</field> | 754 | <field name="method">us_9570_ocb_auto_sync_time</field> |
28 | 755 | </record> | 755 | </record> |
29 | 756 | |||
30 | 757 | <record id="us_6475_set_has_tax_on_po" model="patch.scripts"> | ||
31 | 758 | <field name="method">us_6475_set_has_tax_on_po</field> | ||
32 | 759 | </record> | ||
33 | 756 | </data> | 760 | </data> |
34 | 757 | </openerp> | 761 | </openerp> |
35 | 758 | 762 | ||
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 | 114281 | #: field:sync.version.instance.monitor,platform:0 | 114281 | #: field:sync.version.instance.monitor,platform:0 |
41 | 114282 | msgid "Platform" | 114282 | msgid "Platform" |
42 | 114283 | msgstr "Plate-forme" | 114283 | msgstr "Plate-forme" |
43 | 114284 | |||
44 | 114285 | #. module: purchase | ||
45 | 114286 | #: view:purchase.order:0 | ||
46 | 114287 | msgid "Remove taxes on all PO lines ?" | ||
47 | 114288 | msgstr "Supprimer les taxes sur toutes les lignes ?" | ||
48 | 114289 | |||
49 | 114290 | #. module: purchase | ||
50 | 114291 | #: view:purchase.order:0 | ||
51 | 114292 | msgid "Remove taxes on lines" | ||
52 | 114293 | msgstr "Supprimer les taxes des lignes" | ||
53 | 114294 | |||
54 | 114295 | |||
55 | 114284 | 114296 | ||
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 | 56 | 'model': lambda *a: 'patch.scripts', | 56 | 'model': lambda *a: 'patch.scripts', |
61 | 57 | } | 57 | } |
62 | 58 | 58 | ||
63 | 59 | def us_6475_set_has_tax_on_po(self, cr, uid, *a, **b): | ||
64 | 60 | cr.execute(''' | ||
65 | 61 | update purchase_order | ||
66 | 62 | set has_tax_at_line_level='t' | ||
67 | 63 | where | ||
68 | 64 | id in ( | ||
69 | 65 | select po.id | ||
70 | 66 | from | ||
71 | 67 | purchase_order_line pol, purchase_order po, purchase_order_taxe tax | ||
72 | 68 | where | ||
73 | 69 | po.state in ('draft', 'draft_p', 'validated', 'validated_p') and | ||
74 | 70 | pol.order_id = po.id and | ||
75 | 71 | pol.state not in ('cancel', 'cancel_r') and | ||
76 | 72 | tax.ord_id = pol.id | ||
77 | 73 | ) | ||
78 | 74 | ''') | ||
79 | 75 | self.log_info(cr, uid, 'US-6475: set PO has tax on %d records' % cr.rowcount) | ||
80 | 76 | return True | ||
81 | 77 | |||
82 | 78 | |||
83 | 59 | # UF24.0 | 79 | # UF24.0 |
84 | 60 | def us_9570_ocb_auto_sync_time(self, cr, uid, *a, **b): | 80 | def us_9570_ocb_auto_sync_time(self, cr, uid, *a, **b): |
85 | 61 | entity_obj = self.pool.get('sync.client.entity') | 81 | entity_obj = self.pool.get('sync.client.entity') |
86 | 62 | 82 | ||
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 | 77 | def _amount_all(self, cr, uid, ids, field_name, arg, context=None): | 77 | def _amount_all(self, cr, uid, ids, field_name, arg, context=None): |
92 | 78 | res = {} | 78 | res = {} |
93 | 79 | cur_obj = self.pool.get('res.currency') | 79 | cur_obj = self.pool.get('res.currency') |
95 | 80 | for order in self.browse(cr, uid, ids, context=context): | 80 | pol_obj = self.pool.get('purchase.order.line') |
96 | 81 | tax_obj = self.pool.get('account.tax') | ||
97 | 82 | for order in self.browse(cr, uid, ids, fields_to_fetch=['pricelist_id', 'partner_address_id', 'partner_id', 'tender_id'], context=context): | ||
98 | 81 | res[order.id] = { | 83 | res[order.id] = { |
99 | 82 | 'amount_untaxed': 0.0, | 84 | 'amount_untaxed': 0.0, |
100 | 83 | 'amount_tax': 0.0, | 85 | 'amount_tax': 0.0, |
101 | 84 | 'amount_total': 0.0, | 86 | 'amount_total': 0.0, |
102 | 85 | 'amount_total_tender_currency': 0.0, | 87 | 'amount_total_tender_currency': 0.0, |
103 | 88 | 'has_tax_at_line_level': False, | ||
104 | 86 | } | 89 | } |
106 | 87 | val = val1 = 0.0 | 90 | amount_tax = 0 |
107 | 91 | amount_untaxed = 0 | ||
108 | 88 | cur = order.pricelist_id.currency_id | 92 | cur = order.pricelist_id.currency_id |
116 | 89 | for line in order.order_line: | 93 | |
117 | 90 | if line.state not in ('cancel', 'cancel_r'): | 94 | cr.execute("""select exists( |
118 | 91 | val1 += line.price_subtotal | 95 | select pol.id from purchase_order_line pol, purchase_order_taxe t |
119 | 92 | 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']: | 96 | where |
120 | 93 | val += c.get('amount', 0.0) | 97 | t.ord_id = pol.id and pol.state not in ('cancel', 'cancel_r') and pol.order_id = %s)""", (order.id, )) |
121 | 94 | res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur.rounding, val) | 98 | res[order.id]['has_tax_at_line_level'] = cr.fetchone()[0] |
122 | 95 | res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur.rounding, val1) | 99 | |
123 | 100 | if not res[order.id]['has_tax_at_line_level']: | ||
124 | 101 | 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 | 102 | amount_untaxed = cr.fetchone()[0] or 0 | ||
126 | 103 | |||
127 | 104 | cr.execute("select sum(amount) from account_invoice_tax where purchase_id = %s", (order.id, )) | ||
128 | 105 | amount_tax = cr.fetchone()[0] or 0 | ||
129 | 106 | |||
130 | 107 | else: | ||
131 | 108 | 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 | 109 | pol_ids = [x[0] for x in cr.fetchall()] | ||
133 | 110 | max_size = 400 | ||
134 | 111 | offset = 0 | ||
135 | 112 | while offset < len(pol_ids): | ||
136 | 113 | 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 | 114 | 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 | 115 | amount_untaxed += tax_data.get('total', 0) | ||
139 | 116 | for c in tax_data['taxes']: | ||
140 | 117 | amount_tax += c.get('amount', 0.0) | ||
141 | 118 | offset += max_size | ||
142 | 119 | |||
143 | 120 | res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur.rounding, amount_tax) | ||
144 | 121 | res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur.rounding, amount_untaxed) | ||
145 | 96 | res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax'] | 122 | res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax'] |
146 | 123 | |||
147 | 97 | if order.tender_id and order.tender_id.currency_id \ | 124 | if order.tender_id and order.tender_id.currency_id \ |
148 | 98 | and order.tender_id.currency_id.id != order.pricelist_id.currency_id.id: | 125 | and order.tender_id.currency_id.id != order.pricelist_id.currency_id.id: |
149 | 99 | res[order.id]['amount_total_tender_currency'] = round(cur_obj.compute(cr, uid, cur.id, order.tender_id.currency_id.id, | 126 | 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 | 207 | 234 | ||
152 | 208 | return res | 235 | return res |
153 | 209 | 236 | ||
154 | 237 | def _get_order_from_corner_tax(self, cr, uid, ids, context=None): | ||
155 | 238 | if ids: | ||
156 | 239 | cr.execute('select purchase_id from account_invoice_tax where id in %s', (tuple(ids),)) | ||
157 | 240 | return [x[0] for x in cr.fetchall()] | ||
158 | 241 | return [] | ||
159 | 242 | |||
160 | 210 | def _get_order(self, cr, uid, ids, context=None): | 243 | def _get_order(self, cr, uid, ids, context=None): |
161 | 211 | result = {} | 244 | result = {} |
162 | 212 | for line in self.pool.get('purchase.order.line').browse(cr, uid, ids, fields_to_fetch=['order_id'], context=context): | 245 | 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 | 852 | 'purchase.order.line': (_get_order, ['date_planned'], 10), | 885 | 'purchase.order.line': (_get_order, ['date_planned'], 10), |
165 | 853 | } | 886 | } |
166 | 854 | ), | 887 | ), |
167 | 888 | 'has_tax_at_line_level': fields.function(_amount_all, method=True, type='boolean', string='Tax at line', store= { | ||
168 | 889 | 'purchase.order.line': [ | ||
169 | 890 | (_get_order, ['taxes_id'], 10), | ||
170 | 891 | (_get_order_state_changed, ['state'], 10), | ||
171 | 892 | ] | ||
172 | 893 | }, multi="sums"), | ||
173 | 855 | 'amount_untaxed': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Untaxed Amount', | 894 | 'amount_untaxed': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Untaxed Amount', |
174 | 856 | store={ | 895 | store={ |
175 | 857 | 'purchase.order.line': [ | 896 | 'purchase.order.line': [ |
176 | @@ -864,14 +903,21 @@ | |||
177 | 864 | 'purchase.order.line': [ | 903 | 'purchase.order.line': [ |
178 | 865 | (_get_order, ['price_subtotal', 'taxes_id', 'price_unit', 'product_qty', 'product_id'], 10), | 904 | (_get_order, ['price_subtotal', 'taxes_id', 'price_unit', 'product_qty', 'product_id'], 10), |
179 | 866 | (_get_order_state_changed, ['state'], 10), | 905 | (_get_order_state_changed, ['state'], 10), |
181 | 867 | ] | 906 | (_get_order_from_corner_tax, ['purchase_id', 'amount'], 10), |
182 | 907 | ], | ||
183 | 908 | 'account.invoice.tax': [ | ||
184 | 909 | (_get_order_from_corner_tax, ['purchase_id', 'amount'], 10), | ||
185 | 910 | ], | ||
186 | 868 | }, multi="sums", help="The tax amount"), | 911 | }, multi="sums", help="The tax amount"), |
187 | 869 | 'amount_total': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Total', | 912 | 'amount_total': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Total', |
188 | 870 | store={ | 913 | store={ |
189 | 871 | 'purchase.order.line': [ | 914 | 'purchase.order.line': [ |
190 | 872 | (_get_order, ['price_subtotal', 'taxes_id', 'price_unit', 'product_qty', 'product_id'], 10), | 915 | (_get_order, ['price_subtotal', 'taxes_id', 'price_unit', 'product_qty', 'product_id'], 10), |
191 | 873 | (_get_order_state_changed, ['state'], 10), | 916 | (_get_order_state_changed, ['state'], 10), |
193 | 874 | ] | 917 | ], |
194 | 918 | 'account.invoice.tax': [ | ||
195 | 919 | (_get_order_from_corner_tax, ['purchase_id', 'amount'], 10), | ||
196 | 920 | ], | ||
197 | 875 | }, multi="sums", help="The total amount"), | 921 | }, multi="sums", help="The total amount"), |
198 | 876 | 'amount_total_tender_currency': fields.function(_amount_all, method=True, string='Total (Comparison Currency)', | 922 | 'amount_total_tender_currency': fields.function(_amount_all, method=True, string='Total (Comparison Currency)', |
199 | 877 | digits_compute= dp.get_precision('Purchase Price'), store=False, | 923 | digits_compute= dp.get_precision('Purchase Price'), store=False, |
200 | @@ -927,6 +973,7 @@ | |||
201 | 927 | '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), | 973 | '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 | 928 | 'po_version': fields.integer('Migration: manage old flows', help='v1: dpo reception not synced up, SI/CV generated at PO confirmation', internal=1), | 974 | 'po_version': fields.integer('Migration: manage old flows', help='v1: dpo reception not synced up, SI/CV generated at PO confirmation', internal=1), |
203 | 929 | 'nb_creation_message_nr': fields.function(_get_nb_creation_message_nr, type='integer', method=1, string='Number of NR creation messages'), | 975 | 'nb_creation_message_nr': fields.function(_get_nb_creation_message_nr, type='integer', method=1, string='Number of NR creation messages'), |
204 | 976 | 'tax_line': fields.one2many('account.invoice.tax', 'purchase_id', 'Tax Lines'), | ||
205 | 930 | } | 977 | } |
206 | 931 | _defaults = { | 978 | _defaults = { |
207 | 932 | 'po_version': 2, | 979 | 'po_version': 2, |
208 | @@ -1107,7 +1154,8 @@ | |||
209 | 1107 | if vals.get('pricelist_id') and partner.partner_type == 'external': | 1154 | if vals.get('pricelist_id') and partner.partner_type == 'external': |
210 | 1108 | to_curr_id = self.pool.get('product.pricelist').browse(cr, uid, vals['pricelist_id'], fields_to_fetch=['currency_id'], context=context).currency_id.id | 1155 | 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 | 1109 | 1156 | ||
213 | 1110 | for order in self.browse(cr, uid, ids, fields_to_fetch=['state', 'date_order', 'partner_id', 'order_line', 'pricelist_id'], context=context): | 1157 | 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 | 1158 | line_changed= False | ||
215 | 1111 | if order.state in ('draft', 'draft_p', 'validated') and vals['partner_id'] != order.partner_id.id: | 1159 | if order.state in ('draft', 'draft_p', 'validated') and vals['partner_id'] != order.partner_id.id: |
216 | 1112 | for line in order.order_line: | 1160 | for line in order.order_line: |
217 | 1113 | if line.state in ('draft', 'validated_n', 'validated'): | 1161 | if line.state in ('draft', 'validated_n', 'validated'): |
218 | @@ -1133,8 +1181,15 @@ | |||
219 | 1133 | from_curr_id = order.pricelist_id.currency_id.id | 1181 | from_curr_id = order.pricelist_id.currency_id.id |
220 | 1134 | price_to_convert = line.price_unit | 1182 | price_to_convert = line.price_unit |
221 | 1135 | 1183 | ||
222 | 1184 | line_changed = True | ||
223 | 1136 | new_price = cur_obj.compute(cr, uid, from_curr_id, to_curr_id, price_to_convert, round=False) | 1185 | new_price = cur_obj.compute(cr, uid, from_curr_id, to_curr_id, price_to_convert, round=False) |
224 | 1137 | pol_obj.write(cr, uid, line.id, {'price_unit': new_price}, context=context) | 1186 | pol_obj.write(cr, uid, line.id, {'price_unit': new_price}, context=context) |
225 | 1187 | if line_changed: | ||
226 | 1188 | tax_line_obj = self.pool.get('account.invoice.tax') | ||
227 | 1189 | for tax_line in order.tax_line: | ||
228 | 1190 | new_price = cur_obj.compute(cr, uid, order.pricelist_id.currency_id.id, to_curr_id, tax_line.amount, round=False) | ||
229 | 1191 | tax_line_obj.write(cr, uid, tax_line.id, {'amount': new_price}, context=context) | ||
230 | 1192 | |||
231 | 1138 | 1193 | ||
232 | 1139 | return super(purchase_order, self).write_web(cr, uid, ids, vals, context=context) | 1194 | return super(purchase_order, self).write_web(cr, uid, ids, vals, context=context) |
233 | 1140 | 1195 | ||
234 | @@ -1164,7 +1219,14 @@ | |||
235 | 1164 | if vals.get('partner_id', False): | 1219 | if vals.get('partner_id', False): |
236 | 1165 | partner = self.pool.get('res.partner').browse(cr, uid, vals.get('partner_id'), context=context) | 1220 | partner = self.pool.get('res.partner').browse(cr, uid, vals.get('partner_id'), context=context) |
237 | 1166 | # partner type - always set | 1221 | # partner type - always set |
239 | 1167 | vals.update({'partner_type': partner.partner_type, }) | 1222 | vals.update({'partner_type': partner.partner_type}) |
240 | 1223 | if partner.partner_type != 'external': | ||
241 | 1224 | vals['tax_line'] = False | ||
242 | 1225 | tax_obj = self.pool.get('account.invoice.tax') | ||
243 | 1226 | tax_lines_ids = tax_obj.search(cr, uid, [('purchase_id', 'in', ids)], context=context) | ||
244 | 1227 | if tax_lines_ids: | ||
245 | 1228 | tax_obj.unlink(cr, uid, tax_lines_ids, context=context) | ||
246 | 1229 | |||
247 | 1168 | # internal type (zone) - always set | 1230 | # internal type (zone) - always set |
248 | 1169 | vals.update({'internal_type': partner.zone, }) | 1231 | vals.update({'internal_type': partner.zone, }) |
249 | 1170 | # 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 | 1232 | # 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 | 2750 | 2812 | ||
252 | 2751 | return True | 2813 | return True |
253 | 2752 | 2814 | ||
254 | 2815 | def remove_line_tax(self, cr, uid, ids, context=None): | ||
255 | 2816 | pol_obj = self.pool.get('purchase.order.line') | ||
256 | 2817 | 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 | 2818 | if pol_ids: | ||
258 | 2819 | pol_obj.write(cr, uid, pol_ids, {'taxes_id': [(6, 0, [])]}, context=context) | ||
259 | 2820 | return True | ||
260 | 2821 | |||
261 | 2753 | # CTRL | 2822 | # CTRL |
262 | 2754 | def update_supplier_info(self, cr, uid, ids, context=None, *args, **kwargs): | 2823 | def update_supplier_info(self, cr, uid, ids, context=None, *args, **kwargs): |
263 | 2755 | ''' | 2824 | ''' |
264 | 2756 | 2825 | ||
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 | 28 | ''' | 28 | ''' |
270 | 29 | Return True if the system configuration VAT management is set to True | 29 | Return True if the system configuration VAT management is set to True |
271 | 30 | ''' | 30 | ''' |
272 | 31 | |||
273 | 32 | if context is None: | ||
274 | 33 | context = {} | ||
275 | 31 | vat_ok = self.pool.get('unifield.setup.configuration').get_config(cr, uid).vat_ok | 34 | vat_ok = self.pool.get('unifield.setup.configuration').get_config(cr, uid).vat_ok |
276 | 35 | if vat_ok and 'purchase_id' in context: | ||
277 | 36 | vat_ok = not self.pool.get('account.invoice.tax').search_exists(cr, uid, [('purchase_id', '=', context['purchase_id'])], context=context) | ||
278 | 37 | |||
279 | 32 | res = {} | 38 | res = {} |
280 | 33 | for id in ids: | 39 | for id in ids: |
281 | 34 | res[id] = vat_ok | 40 | res[id] = vat_ok |
282 | @@ -2117,6 +2123,18 @@ | |||
283 | 2117 | if pol.order_id.id not in inv_ids: | 2123 | if pol.order_id.id not in inv_ids: |
284 | 2118 | inv_ids[pol.order_id.id] = pol.order_id.action_invoice_get_or_create(context=context) | 2124 | inv_ids[pol.order_id.id] = pol.order_id.action_invoice_get_or_create(context=context) |
285 | 2119 | 2125 | ||
286 | 2126 | all_taxes = {} | ||
287 | 2127 | if pol.order_id.tax_line and pol.order_id.amount_untaxed: | ||
288 | 2128 | percent = (pol.product_qty * pol.price_unit) / pol.order_id.amount_untaxed | ||
289 | 2129 | all_taxes.setdefault(inv_ids[pol.order_id.id], {}) | ||
290 | 2130 | for tax_line in pol.order_id.tax_line: | ||
291 | 2131 | 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 | 2132 | if key not in all_taxes[inv_ids[pol.order_id.id]]: | ||
293 | 2133 | all_taxes[inv_ids[pol.order_id.id]][key] = { | ||
294 | 2134 | 'tax_line': tax_line, | ||
295 | 2135 | 'amount': 0, | ||
296 | 2136 | } | ||
297 | 2137 | all_taxes[inv_ids[pol.order_id.id]][key]['amount'] += tax_line.amount * percent | ||
298 | 2120 | 2138 | ||
299 | 2121 | if pol.product_id: | 2139 | if pol.product_id: |
300 | 2122 | account_id = pol.product_id.product_tmpl_id.property_account_expense.id | 2140 | account_id = pol.product_id.product_tmpl_id.property_account_expense.id |
301 | @@ -2150,6 +2168,21 @@ | |||
302 | 2150 | }, context=context) | 2168 | }, context=context) |
303 | 2151 | 2169 | ||
304 | 2152 | self.write(cr, uid, ids, {'invoiced': True}, context=context) | 2170 | self.write(cr, uid, ids, {'invoiced': True}, context=context) |
305 | 2171 | |||
306 | 2172 | for inv_id in all_taxes: | ||
307 | 2173 | for key in all_taxes[inv_id]: | ||
308 | 2174 | 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 | 2175 | if not tax_id: | ||
310 | 2176 | self.pool.get('account.invoice.tax').create(cr, uid, { | ||
311 | 2177 | 'invoice_id': inv_id, | ||
312 | 2178 | 'account_tax_id': key[0], | ||
313 | 2179 | 'account_id': key[1], | ||
314 | 2180 | 'partner_id': key[2], | ||
315 | 2181 | 'name': all_taxes[inv_id][key]['tax_line'].name, | ||
316 | 2182 | 'amount': all_taxes[inv_id][key]['amount']}, context=context) | ||
317 | 2183 | else: | ||
318 | 2184 | cr.execute('update account_invoice_tax set amount=amount+%s where id = %s', (all_taxes[inv_id][key]['amount'], tax_id[0])) | ||
319 | 2185 | |||
320 | 2153 | self.pool.get('account.invoice').button_compute(cr, uid, inv_ids.values(), {'type':'in_invoice'}, set_total=True) | 2186 | self.pool.get('account.invoice').button_compute(cr, uid, inv_ids.values(), {'type':'in_invoice'}, set_total=True) |
321 | 2154 | 2187 | ||
322 | 2155 | 2188 | ||
323 | 2156 | 2189 | ||
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 | 386 | <field name="currency_id"/> | 386 | <field name="currency_id"/> |
329 | 387 | </tree> | 387 | </tree> |
330 | 388 | </field> | 388 | </field> |
331 | 389 | <field name="has_tax_at_line_level" invisible="1" /> | ||
332 | 390 | <field name="tax_line" nolabel="1" attrs="{'invisible': [('partner_type', '!=', 'external')], 'readonly': ['|', ('not_beyond_validated','=', False), ('has_tax_at_line_level', '=', True)]}"> | ||
333 | 391 | <tree editable="bottom" string="Taxes"> | ||
334 | 392 | <field name="account_tax_id" on_change="tax_code_change(account_tax_id, parent.amount_untaxed, parent.partner_id, context)" /> | ||
335 | 393 | <field name="name"/> | ||
336 | 394 | |||
337 | 395 | <field name="account_id" | ||
338 | 396 | domain="[('type', 'not in', ['view', 'consolidation']), | ||
339 | 397 | ('user_type_code', '=', 'tax')]"/> | ||
340 | 398 | |||
341 | 399 | <field name="partner_id" readonly="1"/> | ||
342 | 400 | <field name="base" readonly="1"/> | ||
343 | 401 | <field name="amount" /> | ||
344 | 402 | <field name="base_amount" invisible="1"/> | ||
345 | 403 | </tree> | ||
346 | 404 | </field> | ||
347 | 405 | |||
348 | 389 | </page> | 406 | </page> |
349 | 390 | <page string="Notes"> | 407 | <page string="Notes"> |
350 | 391 | <group colspan="4" col="6"> | 408 | <group colspan="4" col="6"> |
351 | @@ -430,6 +447,7 @@ | |||
352 | 430 | <field name="functional_amount_untaxed"/> | 447 | <field name="functional_amount_untaxed"/> |
353 | 431 | <field name="functional_amount_tax"/> | 448 | <field name="functional_amount_tax"/> |
354 | 432 | <field name="functional_amount_total"/> | 449 | <field name="functional_amount_total"/> |
355 | 450 | <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 | 433 | <newline/> | 451 | <newline/> |
357 | 434 | <field name="total_price_include_transport" readonly="1" attrs="{'invisible': ['|', ('categ', '=', 'transport'), ('display_intl_transport_ok', '=', False)]}"/> | 452 | <field name="total_price_include_transport" readonly="1" attrs="{'invisible': ['|', ('categ', '=', 'transport'), ('display_intl_transport_ok', '=', False)]}"/> |
358 | 435 | <newline/> | 453 | <newline/> |
359 | 436 | 454 | ||
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 | 879 | self.generate_invoice(cr, uid, pol_to_invoice.keys(), context=context) | 879 | self.generate_invoice(cr, uid, pol_to_invoice.keys(), context=context) |
365 | 880 | return True | 880 | return True |
366 | 881 | 881 | ||
367 | 882 | def update_tax_corner(self, cr, uid, ids, context=None): | ||
368 | 883 | for pol in self.browse(cr, uid, ids, fields_to_fetch=['product_qty', 'price_unit', 'order_id'], context=context): | ||
369 | 884 | if pol.order_id.tax_line and pol.order_id.amount_untaxed: | ||
370 | 885 | percent = (pol.product_qty * pol.price_unit) / pol.order_id.amount_untaxed | ||
371 | 886 | for tax_line in pol.order_id.tax_line: | ||
372 | 887 | self.pool.get('account.invoice.tax').write(cr, uid, tax_line.id, {'amount': round(tax_line.amount * (1 - percent), 2)}, context=context) | ||
373 | 888 | return True | ||
374 | 882 | 889 | ||
375 | 883 | def action_cancel(self, cr, uid, ids, context=None): | 890 | def action_cancel(self, cr, uid, ids, context=None): |
376 | 884 | ''' | 891 | ''' |
377 | @@ -900,6 +907,7 @@ | |||
378 | 900 | if pol.cancelled_by_sync: | 907 | if pol.cancelled_by_sync: |
379 | 901 | sol_obj.write(cr, uid, pol.linked_sol_id.id, {'cancelled_by_sync': True}, context=context) | 908 | sol_obj.write(cr, uid, pol.linked_sol_id.id, {'cancelled_by_sync': True}, context=context) |
380 | 902 | wf_service.trg_validate(uid, 'sale.order.line', pol.linked_sol_id.id, 'cancel', cr) | 909 | wf_service.trg_validate(uid, 'sale.order.line', pol.linked_sol_id.id, 'cancel', cr) |
381 | 910 | self.update_tax_corner(cr, uid, ids, context=context) | ||
382 | 903 | self.write(cr, uid, ids, {'state': 'cancel'}, context=context) | 911 | self.write(cr, uid, ids, {'state': 'cancel'}, context=context) |
383 | 904 | 912 | ||
384 | 905 | return True | 913 | return True |
385 | @@ -925,6 +933,7 @@ | |||
386 | 925 | 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) | 933 | 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 | 926 | wf_service.trg_validate(uid, 'sale.order.line', pol.linked_sol_id.id, 'cancel_r', cr) | 934 | wf_service.trg_validate(uid, 'sale.order.line', pol.linked_sol_id.id, 'cancel_r', cr) |
388 | 927 | 935 | ||
389 | 936 | self.update_tax_corner(cr, uid, ids, context=context) | ||
390 | 928 | self.write(cr, uid, ids, {'state': 'cancel_r'}, context=context) | 937 | self.write(cr, uid, ids, {'state': 'cancel_r'}, context=context) |
391 | 929 | 938 | ||
392 | 930 | return True | 939 | return True |
393 | 931 | 940 | ||
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 | 78 | currency_obj = self.pool.get('res.currency') | 78 | currency_obj = self.pool.get('res.currency') |
399 | 79 | line_obj = self.pool.get('purchase.order.line') | 79 | line_obj = self.pool.get('purchase.order.line') |
400 | 80 | order_obj = self.pool.get('purchase.order') | 80 | order_obj = self.pool.get('purchase.order') |
401 | 81 | tax_line_obj = self.pool.get('account.invoice.tax') | ||
402 | 81 | 82 | ||
403 | 82 | for wiz in self.browse(cr, uid, ids, context=context): | 83 | for wiz in self.browse(cr, uid, ids, context=context): |
404 | 83 | for line in wiz.order_id.order_line: | 84 | for line in wiz.order_id.order_line: |
405 | 84 | 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) | 85 | 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 | 85 | line_obj.write(cr, uid, line.id, {'price_unit': new_price}, context=c) | 86 | line_obj.write(cr, uid, line.id, {'price_unit': new_price}, context=c) |
407 | 86 | 87 | ||
408 | 88 | for tax_line in wiz.order_id.tax_line: | ||
409 | 89 | 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 | 90 | tax_line_obj.write(cr, uid, tax_line.id, {'amount': new_price}, context=c) | ||
411 | 91 | |||
412 | 87 | order_data = {'pricelist_id': wiz.new_pricelist_id.id,} | 92 | order_data = {'pricelist_id': wiz.new_pricelist_id.id,} |
413 | 88 | # Set at least, the functional currency | 93 | # Set at least, the functional currency |
414 | 89 | currency_ids = [self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id] | 94 | currency_ids = [self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id] |
415 | 90 | 95 | ||
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 | 1853 | for move_line in picking.move_lines: | 1853 | for move_line in picking.move_lines: |
421 | 1854 | self.action_invoice_create_line(cr, uid, picking, move_line, invoice_id, group, inv_type, partner, context) | 1854 | self.action_invoice_create_line(cr, uid, picking, move_line, invoice_id, group, inv_type, partner, context) |
422 | 1855 | 1855 | ||
423 | 1856 | if picking.purchase_id and picking.purchase_id.tax_line: | ||
424 | 1857 | total_po = picking.purchase_id.amount_untaxed | ||
425 | 1858 | total_invoice = invoice_obj.browse(cr, uid, [invoice_id], fields_to_fetch=['amount_untaxed'], context=context)[0].amount_untaxed | ||
426 | 1859 | if total_po and total_invoice: | ||
427 | 1860 | for tax_line in move_line.purchase_line_id.order_id.tax_line: | ||
428 | 1861 | self.pool.get('account.invoice.tax').create(cr, uid, { | ||
429 | 1862 | 'invoice_id': invoice_id, | ||
430 | 1863 | 'account_tax_id': tax_line.account_tax_id.id, | ||
431 | 1864 | 'account_id': tax_line.account_id.id, | ||
432 | 1865 | 'partner_id': tax_line.partner_id.id, | ||
433 | 1866 | 'name': tax_line.name, | ||
434 | 1867 | 'base_amount': total_invoice, | ||
435 | 1868 | 'amount': tax_line.amount * total_invoice / total_po}, context=context) | ||
436 | 1869 | |||
437 | 1870 | |||
438 | 1856 | invoice_obj.button_compute(cr, uid, [invoice_id], context=context, | 1871 | invoice_obj.button_compute(cr, uid, [invoice_id], context=context, |
439 | 1857 | set_total=(inv_type in ('in_invoice', 'in_refund'))) | 1872 | set_total=(inv_type in ('in_invoice', 'in_refund'))) |
440 | 1858 | self.write(cr, uid, [picking.id], { | 1873 | self.write(cr, uid, [picking.id], { |