mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2026-10-25 23:40:05 -05:00
[PATCH] Upstream patch - 05032022
This commit is contained in:
1 parent
891e896188
commit
17060f2ede
6 files changed
+107
-80
No files matched your search
@@ -336,36 +336,6 @@ class AccountEdiFormat(models.Model):
|
||||
if elements:
|
||||
invoice_form.l10n_it_stamp_duty = float(elements[0].text)
|
||||
|
||||
# List of all amount discount (will be add after all article to avoid to have a negative sum)
|
||||
discount_list = []
|
||||
percentage_global_discount = 1.0
|
||||
|
||||
# Global discount. <2.1.1.8>
|
||||
discount_elements = body_tree.xpath('.//DatiGeneraliDocumento/ScontoMaggiorazione')
|
||||
total_discount_amount = 0.0
|
||||
if discount_elements:
|
||||
for discount_element in discount_elements:
|
||||
discount_line = discount_element.xpath('.//Tipo')
|
||||
discount_sign = -1
|
||||
if discount_line and discount_line[0].text == 'SC':
|
||||
discount_sign = 1
|
||||
discount_percentage = discount_element.xpath('.//Percentuale')
|
||||
if discount_percentage and discount_percentage[0].text:
|
||||
percentage_global_discount *= 1 - float(discount_percentage[0].text)/100 * discount_sign
|
||||
|
||||
discount_amount_text = discount_element.xpath('.//Importo')
|
||||
if discount_amount_text and discount_amount_text[0].text:
|
||||
discount_amount = float(discount_amount_text[0].text) * discount_sign * -1
|
||||
discount = {}
|
||||
discount["seq"] = 0
|
||||
|
||||
if discount_amount < 0:
|
||||
discount["name"] = _('GLOBAL DISCOUNT')
|
||||
else:
|
||||
discount["name"] = _('GLOBAL EXTRA CHARGE')
|
||||
discount["amount"] = discount_amount
|
||||
discount["tax"] = []
|
||||
discount_list.append(discount)
|
||||
|
||||
# Comment. <2.1.1.11>
|
||||
elements = body_tree.xpath('.//DatiGeneraliDocumento//Causale')
|
||||
@@ -445,7 +415,7 @@ class AccountEdiFormat(models.Model):
|
||||
# Sequence.
|
||||
line_elements = element.xpath('.//NumeroLinea')
|
||||
if line_elements:
|
||||
invoice_line_form.sequence = int(line_elements[0].text) * 2
|
||||
invoice_line_form.sequence = int(line_elements[0].text)
|
||||
|
||||
# Product.
|
||||
line_elements = element.xpath('.//Descrizione')
|
||||
@@ -524,57 +494,51 @@ class AccountEdiFormat(models.Model):
|
||||
percentage,
|
||||
invoice_line_form.name))
|
||||
|
||||
# Discount in cascade mode.
|
||||
# if 3 discounts : -10% -50€ -20%
|
||||
# the result must be : (((price -10%)-50€) -20%)
|
||||
# Generic form : (((price -P1%)-A1€) -P2%)
|
||||
# It will be split in two parts: fix amount and pourcent amount
|
||||
# example: (((((price - A1€) -P2%) -A3€) -A4€) -P5€)
|
||||
# pourcent: 1-(1-P2)*(1-P5)
|
||||
# fix amount: A1*(1-P2)*(1-P5)+A3*(1-P5)+A4*(1-P5) (we must take account of all
|
||||
# percentage present after the fix amount)
|
||||
line_elements = element.xpath('.//ScontoMaggiorazione')
|
||||
total_discount_amount = 0.0
|
||||
total_discount_percentage = percentage_global_discount
|
||||
if line_elements:
|
||||
for line_element in line_elements:
|
||||
discount_line = line_element.xpath('.//Tipo')
|
||||
discount_sign = -1
|
||||
if discount_line and discount_line[0].text == 'SC':
|
||||
discount_sign = 1
|
||||
discount_percentage = line_element.xpath('.//Percentuale')
|
||||
if discount_percentage and discount_percentage[0].text:
|
||||
pourcentage_actual = 1 - float(discount_percentage[0].text)/100 * discount_sign
|
||||
total_discount_percentage *= pourcentage_actual
|
||||
total_discount_amount *= pourcentage_actual
|
||||
# Discounts
|
||||
discount_elements = element.xpath('.//ScontoMaggiorazione')
|
||||
if discount_elements:
|
||||
discount_element = discount_elements[0]
|
||||
discount_percentage = discount_element.xpath('.//Percentuale')
|
||||
# Special case of only 1 percentage discount
|
||||
if discount_percentage and len(discount_elements) == 1:
|
||||
discount_type = discount_element.xpath('.//Tipo')
|
||||
discount_sign = 1
|
||||
if discount_type and discount_type[0].text == 'MG':
|
||||
discount_sign = -1
|
||||
invoice_line_form.discount = discount_sign * float(discount_percentage[0].text)
|
||||
# Discounts in cascade summarized in 1 percentage
|
||||
else:
|
||||
total = float(element.xpath('.//PrezzoTotale')[0].text)
|
||||
discount = 100 - (100 * total) / (invoice_line_form.quantity * invoice_line_form.price_unit)
|
||||
invoice_line_form.discount = discount
|
||||
|
||||
discount_amount = line_element.xpath('.//Importo')
|
||||
if discount_amount and discount_amount[0].text:
|
||||
total_discount_amount += float(discount_amount[0].text) * discount_sign * -1
|
||||
|
||||
# Save amount discount.
|
||||
if total_discount_amount != 0:
|
||||
discount = {}
|
||||
discount["seq"] = invoice_line_form.sequence + 1
|
||||
# Global discount summarized in 1 amount
|
||||
discount_elements = body_tree.xpath('.//DatiGeneraliDocumento/ScontoMaggiorazione')
|
||||
if discount_elements:
|
||||
taxable_amount = invoice_form.amount_untaxed
|
||||
discounted_amount = taxable_amount
|
||||
for discount_element in discount_elements:
|
||||
discount_type = discount_element.xpath('.//Tipo')
|
||||
discount_sign = 1
|
||||
if discount_type and discount_type[0].text == 'MG':
|
||||
discount_sign = -1
|
||||
discount_amount = discount_element.xpath('.//Importo')
|
||||
if discount_amount:
|
||||
discounted_amount -= discount_sign * float(discount_amount[0].text)
|
||||
continue
|
||||
discount_percentage = discount_element.xpath('.//Percentuale')
|
||||
if discount_percentage:
|
||||
discounted_amount *= 1 - discount_sign * float(discount_percentage[0].text) / 100
|
||||
|
||||
if total_discount_amount < 0:
|
||||
discount["name"] = _('DISCOUNT: %s', invoice_line_form.name)
|
||||
else:
|
||||
discount["name"] = _('EXTRA CHARGE: %s', invoice_line_form.name)
|
||||
discount["amount"] = total_discount_amount
|
||||
discount["tax"] = []
|
||||
for tax in invoice_line_form.tax_ids:
|
||||
discount["tax"].append(tax)
|
||||
discount_list.append(discount)
|
||||
invoice_line_form.discount = (1 - total_discount_percentage) * 100
|
||||
general_discount = discounted_amount - taxable_amount
|
||||
sequence = len(elements) + 1
|
||||
|
||||
# Apply amount discount.
|
||||
for discount in discount_list:
|
||||
with invoice_form.invoice_line_ids.new() as invoice_line_form_discount:
|
||||
invoice_line_form_discount.tax_ids.clear()
|
||||
invoice_line_form_discount.sequence = discount["seq"]
|
||||
invoice_line_form_discount.name = discount["name"]
|
||||
invoice_line_form_discount.price_unit = discount["amount"]
|
||||
with invoice_form.invoice_line_ids.new() as invoice_line_global_discount:
|
||||
invoice_line_global_discount.tax_ids.clear()
|
||||
invoice_line_global_discount.sequence = sequence
|
||||
invoice_line_global_discount.name = 'SCONTO' if general_discount < 0 else 'MAGGIORAZIONE'
|
||||
invoice_line_global_discount.price_unit = general_discount
|
||||
|
||||
new_invoice = invoice_form.save()
|
||||
new_invoice.l10n_it_send_state = "other"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<field name="type" invisible="1"/>
|
||||
<field name="street" placeholder="Street" class="o_address_street"
|
||||
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}"/>
|
||||
<field name="street2" invisible="1"/>
|
||||
<field name="l10n_pe_district" placeholder="District..." class="o_address_street"/>
|
||||
<field name="city"/>
|
||||
<field name="state_id" class="o_address_state" placeholder="State..." options='{"no_open": True}'
|
||||
|
||||
@@ -10,7 +10,7 @@ class SaleOrderLine(models.Model):
|
||||
"Margin", compute='_compute_margin',
|
||||
digits='Product Price', store=True, groups="base.group_user")
|
||||
margin_percent = fields.Float(
|
||||
"Margin (%)", compute='_compute_margin', store=True, groups="base.group_user")
|
||||
"Margin (%)", compute='_compute_margin', store=True, groups="base.group_user", group_operator="avg")
|
||||
purchase_price = fields.Float(
|
||||
string='Cost', compute="_compute_purchase_price",
|
||||
digits='Product Price', store=True, readonly=False,
|
||||
|
||||
@@ -55,4 +55,15 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="sale_margin_sale_order_pivot">
|
||||
<field name="name">sale.order.margin.view.graph</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="inherit_id" ref="sale.view_sale_order_graph"/>
|
||||
<field name="arch" type="xml">
|
||||
<graph position="inside">
|
||||
<field name="margin_percent" invisible="1"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</flectra>
|
||||
@@ -1396,7 +1396,8 @@ class StockMove(models.Model):
|
||||
grouped_move_lines_out[k] = sum(self.env['stock.move.line'].concat(*list(g)).mapped('product_qty'))
|
||||
available_move_lines = {key: grouped_move_lines_in[key] - grouped_move_lines_out.get(key, 0) for key in grouped_move_lines_in.keys()}
|
||||
# pop key if the quantity available amount to 0
|
||||
available_move_lines = dict((k, v) for k, v in available_move_lines.items() if v)
|
||||
rounding = move.product_id.uom_id.rounding
|
||||
available_move_lines = dict((k, v) for k, v in available_move_lines.items() if float_compare(v, 0, precision_rounding=rounding) > 0)
|
||||
|
||||
if not available_move_lines:
|
||||
continue
|
||||
|
||||
@@ -930,3 +930,53 @@ class TestPacking(TestPackingCommon):
|
||||
picking.button_validate()
|
||||
|
||||
self.assertEqual(package_level.location_id, shelf1_location)
|
||||
|
||||
def test_2_steps_and_reservation(self):
|
||||
""" When creating a backorder in a two steps flow, the reservation should be resilient
|
||||
to the change of quantity in any move of the chain. The test scenario is the following:
|
||||
|
||||
- move (5 units) CONFIRMED
|
||||
/
|
||||
move orig (10 units) DONE -
|
||||
\ - move sibling (5 units) DONE
|
||||
|
||||
The confirmed move can be assigned because on the 10 units validated on the move
|
||||
orig, only 5 have already been validated in the sibling move. If before the
|
||||
reservation the move orig is unlocked and the quantity is changed from 10 to 1, the
|
||||
confirmed move cannot reserve any quantity anymore but should be able to call
|
||||
action_assign without any error."""
|
||||
|
||||
self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 20.0)
|
||||
self.env['stock.quant']._update_available_quantity(self.productA, self.pack_location, 30.0)
|
||||
ship_move_a = self.env['stock.move'].create({
|
||||
'name': 'The ship move',
|
||||
'product_id': self.productA.id,
|
||||
'product_uom_qty': 20.0,
|
||||
'product_uom': self.productA.uom_id.id,
|
||||
'location_id': self.ship_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'warehouse_id': self.warehouse.id,
|
||||
'picking_type_id': self.warehouse.out_type_id.id,
|
||||
'procure_method': 'make_to_order',
|
||||
'state': 'draft',
|
||||
})
|
||||
ship_move_a._assign_picking()
|
||||
ship_move_a._action_confirm()
|
||||
pack_move_a = ship_move_a.move_orig_ids[0]
|
||||
pick_move_a = pack_move_a.move_orig_ids[0]
|
||||
|
||||
pick_move_a.quantity_done = 20
|
||||
pick_move_a._action_done()
|
||||
|
||||
pack_move_a.quantity_done = 10
|
||||
picking = pack_move_a.picking_id
|
||||
action_data = picking.button_validate()
|
||||
backorder_wizard = Form(self.env['stock.backorder.confirmation'].with_context(action_data['context'])).save()
|
||||
backorder_wizard.process()
|
||||
|
||||
# change validated quantity of the first step
|
||||
pick_move_a.quantity_done = 5
|
||||
|
||||
# check the backorder can still be reserved
|
||||
backorder = (pack_move_a.move_orig_ids.move_dest_ids - pack_move_a).picking_id
|
||||
backorder.action_assign()
|
||||
Reference in new issue
Block a user