fix(billing): name ledger partners by company, not the NexaCloud user's full_name
One operator (e.g. "Gurpreet Singh") manages several distinct customer businesses; naming partners from full_name mislabeled Mobility Specialties Inc and Apex Vita Corporation as "Gurpreet Singh". Read the company field, name the partner by company (mark is_company), and rewrite existing partners so prior full_name-based names are corrected on re-ingest. 75 tests green.
This commit is contained in:
@@ -120,6 +120,14 @@ class TestLedgerIngest(TransactionCase):
|
|||||||
self.assertAlmostEqual(mv.amount_untaxed, 200.0, places=2) # captured via reconciling line
|
self.assertAlmostEqual(mv.amount_untaxed, 200.0, places=2) # captured via reconciling line
|
||||||
self.assertTrue(any('base/unitemized' in (l.name or '') for l in mv.invoice_line_ids))
|
self.assertTrue(any('base/unitemized' in (l.name or '') for l in mv.invoice_line_ids))
|
||||||
|
|
||||||
|
def test_partner_named_by_company_not_person(self):
|
||||||
|
data = _inv_fixture()
|
||||||
|
data[0]['partner_company'] = 'Acme Holdings Inc' # full_name is "Acme"; company wins
|
||||||
|
self.W._ingest_invoices(data, post=False)
|
||||||
|
mv = self.Move.search([('x_fc_nexacloud_invoice_id', '=', 'inv-1')])
|
||||||
|
self.assertEqual(mv.partner_id.name, 'Acme Holdings Inc')
|
||||||
|
self.assertTrue(mv.partner_id.is_company)
|
||||||
|
|
||||||
def test_prune_shadow_removes_shadow_subs_only(self):
|
def test_prune_shadow_removes_shadow_subs_only(self):
|
||||||
p = self.env['res.partner'].sudo().create({'name': 'X'})
|
p = self.env['res.partner'].sudo().create({'name': 'X'})
|
||||||
shadow = self.env['sale.order'].sudo().create({'partner_id': p.id, 'x_fc_shadow': True})
|
shadow = self.env['sale.order'].sudo().create({'partner_id': p.id, 'x_fc_shadow': True})
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class FusionBillingInvoiceLedgerWizard(models.TransientModel):
|
|||||||
cur.execute(
|
cur.execute(
|
||||||
"SELECT i.id, i.stripe_invoice_id, i.invoice_number, "
|
"SELECT i.id, i.stripe_invoice_id, i.invoice_number, "
|
||||||
"i.user_id AS user_external_id, u.full_name AS partner_name, "
|
"i.user_id AS user_external_id, u.full_name AS partner_name, "
|
||||||
|
"u.company AS partner_company, "
|
||||||
"COALESCE(u.billing_email, u.email) AS partner_email, "
|
"COALESCE(u.billing_email, u.email) AS partner_email, "
|
||||||
"i.created_at AS invoice_date, i.currency, i.status, i.subtotal, i.tax, "
|
"i.created_at AS invoice_date, i.currency, i.status, i.subtotal, i.tax, "
|
||||||
"i.amount_paid, i.paid_at "
|
"i.amount_paid, i.paid_at "
|
||||||
@@ -125,13 +126,16 @@ class FusionBillingInvoiceLedgerWizard(models.TransientModel):
|
|||||||
if existing and existing.state != "draft":
|
if existing and existing.state != "draft":
|
||||||
summary["skipped"].append({"id": nc_id, "reason": "already posted"})
|
summary["skipped"].append({"id": nc_id, "reason": "already posted"})
|
||||||
continue
|
continue
|
||||||
|
partner = self._fc_partner_for(inv)
|
||||||
if existing:
|
if existing:
|
||||||
existing.invoice_line_ids.unlink() # draft: replace lines
|
existing.invoice_line_ids.unlink() # draft: replace lines
|
||||||
|
if existing.partner_id != partner:
|
||||||
|
existing.partner_id = partner.id
|
||||||
move = existing
|
move = existing
|
||||||
else:
|
else:
|
||||||
move = Move.create({
|
move = Move.create({
|
||||||
"move_type": "out_invoice",
|
"move_type": "out_invoice",
|
||||||
"partner_id": self._fc_partner_for(inv).id,
|
"partner_id": partner.id,
|
||||||
"invoice_date": inv.get("invoice_date"),
|
"invoice_date": inv.get("invoice_date"),
|
||||||
"ref": inv.get("invoice_number"),
|
"ref": inv.get("invoice_number"),
|
||||||
"currency_id": cad.id,
|
"currency_id": cad.id,
|
||||||
@@ -245,10 +249,17 @@ class FusionBillingInvoiceLedgerWizard(models.TransientModel):
|
|||||||
if not service:
|
if not service:
|
||||||
service = self.env["fusion.billing.service"].create(
|
service = self.env["fusion.billing.service"].create(
|
||||||
{"name": "NexaCloud", "code": "nexacloud"})
|
{"name": "NexaCloud", "code": "nexacloud"})
|
||||||
|
company = (inv.get("partner_company") or "").strip()
|
||||||
|
name = company or inv.get("partner_name") or str(inv.get("user_external_id"))
|
||||||
link = self.env["fusion.billing.account.link"]._resolve_or_create_partner(
|
link = self.env["fusion.billing.account.link"]._resolve_or_create_partner(
|
||||||
service, str(inv.get("user_external_id")),
|
service, str(inv.get("user_external_id")), name=name, email=inv.get("partner_email"))
|
||||||
name=inv.get("partner_name"), email=inv.get("partner_email"))
|
partner = link.partner_id
|
||||||
return link.partner_id
|
# Name the partner for the BUSINESS (company), not the NexaCloud user's full_name —
|
||||||
|
# one person (e.g. "Gurpreet Singh") can manage several distinct customer businesses.
|
||||||
|
# Rewrite an existing partner so earlier full_name-based names get corrected.
|
||||||
|
if company and (partner.name != company or not partner.is_company):
|
||||||
|
partner.write({"name": company, "is_company": True})
|
||||||
|
return partner
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _fc_stripe_journal(self):
|
def _fc_stripe_journal(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user