/** * Create an invoice from a quote. * * @param Quote $quote * * @return Invoice */ public function createFromQuote(Quote $quote) { $invoice = new Invoice(); $now = Carbon::now(); $invoice->setCreated($now); $invoice->setClient($quote->getClient()); $invoice->setBaseTotal($quote->getBaseTotal()); $invoice->setDiscount($quote->getDiscount()); $invoice->setNotes($quote->getNotes()); $invoice->setTotal($quote->getTotal()); $invoice->setTerms($quote->getTerms()); $invoice->setUsers($quote->getUsers()->toArray()); $invoice->setBalance($invoice->getTotal()); if (null !== $quote->getTax()) { $invoice->setTax($quote->getTax()); } /** @var \CSBill\QuoteBundle\Entity\Item $item */ foreach ($quote->getItems() as $item) { $invoiceItem = new Item(); $invoiceItem->setCreated($now); $invoiceItem->setTotal($item->getTotal()); $invoiceItem->setDescription($item->getDescription()); $invoiceItem->setPrice($item->getPrice()); $invoiceItem->setQty($item->getQty()); if (null !== $item->getTax()) { $invoiceItem->setTax($item->getTax()); } $invoice->addItem($invoiceItem); } $this->create($invoice); $this->accept($invoice); // ?? Do we really want to accept it immediately after creating it? return $invoice; }
/** * @param Quote|Invoice $object * @param Money $total * * @return mixed */ private function setDiscount($object, Money $total) { if (null !== $object->getDiscount()) { $discount = $total->multiply($object->getDiscount()); $total = $total->subtract($discount); return $total; } return $total; }
public function testCreateFromQuote() { $currency = new Currency('USD'); $this->dispatcher->shouldReceive('dispatch')->withAnyArgs(); $client = new Client(); $client->setName('Test Client'); $client->setWebsite('http://example.com'); $client->setCreated(new \DateTime('NOW')); $tax = new Tax(); $tax->setName('VAT'); $tax->setRate('14'); $tax->setType(Tax::TYPE_INCLUSIVE); $item = new Item(); $item->setTax($tax); $item->setDescription('Item Description'); $item->setCreated(new \DateTime('now')); $item->setPrice(new Money(120, $currency)); $item->setQty(10); $item->setTotal(new Money(12 * 10, $currency)); $quote = new Quote(); $quote->setBaseTotal(new Money(123, $currency)); $quote->setDiscount(new Money(12, $currency)); $quote->setNotes('Notes'); $quote->setTax(new Money(432, $currency)); $quote->setTerms('Terms'); $quote->setTotal(new Money(987, $currency)); $quote->setClient($client); $quote->addItem($item); $invoice = $this->manager->createFromQuote($quote); $this->assertSame($quote->getTotal(), $invoice->getTotal()); $this->assertSame($quote->getBaseTotal(), $invoice->getBaseTotal()); $this->assertSame($quote->getDiscount(), $invoice->getDiscount()); $this->assertSame($quote->getNotes(), $invoice->getNotes()); $this->assertSame($quote->getTerms(), $invoice->getTerms()); $this->assertSame($quote->getTax(), $invoice->getTax()); $this->assertSame($client, $invoice->getClient()); $this->assertSame('new', $invoice->getStatus()); $this->assertNotSame($quote->getUuid(), $invoice->getUuid()); $this->assertNull($invoice->getId()); $this->assertCount(1, $invoice->getItems()); /** @var \CSBill\InvoiceBundle\Entity\item[] $invoiceItem */ $invoiceItem = $invoice->getItems(); $this->assertInstanceOf('CSBill\\InvoiceBundle\\Entity\\item', $invoiceItem[0]); $this->assertSame($item->getTax(), $invoiceItem[0]->getTax()); $this->assertSame($item->getDescription(), $invoiceItem[0]->getDescription()); $this->assertInstanceOf('DateTime', $invoiceItem[0]->getCreated()); $this->assertSame($item->getPrice(), $invoiceItem[0]->getPrice()); $this->assertSame($item->getQty(), $invoiceItem[0]->getQty()); }
/** * Create a new Quote. * * @param Request $request * @param Client $client * * @return Response */ public function createAction(Request $request, Client $client = null) { /** @var \CSBill\ClientBundle\Repository\ClientRepository $clients */ $clients = $this->getRepository('CSBillClientBundle:Client'); if (!$clients->getTotalClients() > 0) { return $this->render('CSBillQuoteBundle:Default:empty_clients.html.twig'); } $quote = new Quote(); $quote->setClient($client); $form = $this->createForm(QuoteType::class, $quote); $form->handleRequest($request); if ($form->isValid()) { $action = $request->request->get('save'); $this->saveQuote($quote, $action); $this->get('event_dispatcher')->dispatch(QuoteEvents::QUOTE_POST_CREATE, new QuoteEvent($quote)); $this->flash($this->trans('quote.action.create.success'), 'success'); return $this->redirect($this->generateUrl('_quotes_view', ['id' => $quote->getId()])); } return $this->render('CSBillQuoteBundle:Default:create.html.twig', ['form' => $form->createView()]); }
/** * Add quote. * * @param Quote $quote * * @return Client */ public function addQuote(Quote $quote) { $this->quotes[] = $quote; $quote->setClient($this); return $this; }
/** * Emails a quote to the customers. * * @param Quote $quote * * @return int If the email was successfully sent */ public function sendQuote(Quote $quote) { $htmlTemplate = $this->getTemplate('CSBillQuoteBundle:Email:quote.html.twig', ['quote' => $quote]); $textTemplate = $this->getTemplate('CSBillQuoteBundle:Email:quote.txt.twig', ['quote' => $quote]); $subject = $this->getSubject('quote.email_subject', $quote->getId()); $users = []; foreach ($quote->getUsers() as $user) { /* @var \CSBill\ClientBundle\Entity\Contact $user */ $users[(string) $user->getEmail()] = $user->getFirstName() . ' ' . $user->getLastName(); } $event = new QuoteEvent(); $event->setQuote($quote); $bcc = (string) $this->settings->get('quote.bcc_address'); $sent = $this->sendMessage($subject, $users, $htmlTemplate, $textTemplate, $event, $bcc); return $sent; }
/** * @param Quote $quote * * @return Quote */ public function duplicate(Quote $quote) { // We don't use 'clone', since cloning aq quote will clone all the item id's and nested values. // We rather set it manually $newQuote = new Quote(); $now = Carbon::now(); $newQuote->setCreated($now); $newQuote->setClient($quote->getClient()); $newQuote->setBaseTotal($quote->getBaseTotal()); $newQuote->setDiscount($quote->getDiscount()); $newQuote->setNotes($quote->getNotes()); $newQuote->setTotal($quote->getTotal()); $newQuote->setTerms($quote->getTerms()); $newQuote->setUsers($quote->getUsers()->toArray()); if (null !== $quote->getTax()) { $newQuote->setTax($quote->getTax()); } foreach ($quote->getItems() as $item) { $invoiceItem = new Item(); $invoiceItem->setCreated($now); $invoiceItem->setTotal($item->getTotal()); $invoiceItem->setDescription($item->getDescription()); $invoiceItem->setPrice($item->getPrice()); $invoiceItem->setQty($item->getQty()); if (null !== $item->getTax()) { $invoiceItem->setTax($item->getTax()); } $newQuote->addItem($invoiceItem); } $this->dispatcher->dispatch(QuoteEvents::QUOTE_PRE_CREATE, new QuoteEvent($newQuote)); $stateMachine = $this->stateMachine->get($newQuote, Graph::GRAPH); if ($stateMachine->can(Graph::TRANSITION_NEW)) { $stateMachine->apply(Graph::TRANSITION_NEW); } $this->entityManager->persist($newQuote); $this->entityManager->flush(); $this->dispatcher->dispatch(QuoteEvents::QUOTE_POST_CREATE, new QuoteEvent($newQuote)); return $newQuote; }
public static function view(Quote $quote) { return ['View Quote', ['extras' => ['icon' => 'eye'], 'route' => '_quotes_view', 'routeParameters' => ['id' => $quote->getId()]]]; }
/** * Emails a quote to the customers. * * @param Quote $quote * * @return int If the email was successfully sent */ public function sendQuote(Quote $quote) { // TODO : this needs to come from settings or somewhere so it can be extended $htmlTemplate = $this->getTemplate('CSBillQuoteBundle:Email:quote.html.twig', array('quote' => $quote)); $textTemplate = $this->getTemplate('CSBillQuoteBundle:Email:quote.txt.twig', array('quote' => $quote)); $subject = $this->getSubject('quote.email_subject', $quote->getId()); $users = array(); foreach ($quote->getUsers() as $user) { /* @var \CSBill\ClientBundle\Entity\Contact $user */ $users[(string) $user->getPrimaryDetail('email')] = $user->getFirstname() . ' ' . $user->getLastname(); } $event = new QuoteEvent(); $event->setQuote($quote); $bcc = (string) $this->settings->get('quote.bcc_address'); $sent = $this->sendMessage($subject, $users, $htmlTemplate, $textTemplate, $event, $bcc); return $sent; }
/** * @ApiDoc( * statusCodes={ * 201="Returned when successful", * 400="Returned when the validation fails", * 403="Returned when the user is not authorized", * }, * resource=true, * description="Create a new quote", * input="CSBill\QuoteBundle\Form\Type\QuoteType", * output="CSBill\QuoteBundle\Entity\Quote", * authentication=true, * ) * * @param Request $request * * @Rest\Post(path="/quotes") * * @return Response */ public function createQuoteAction(Request $request) { $entity = new Entity\Quote(); $entity->setStatus($request->request->get('status', Graph::STATUS_DRAFT)); $request->request->remove('status'); return $this->manageForm($request, 'quote', $entity, Response::HTTP_CREATED); }